私は私が解決しようとしている小さなパズルを持っているし、それについて移動する方法がわからないです... MVVMのアプローチに基づいてクラスデシリアライゼーションとWPFのバインディング
WPFアプリケーション...
私が持っています
namespace Lib
{
public sealed class SubstitutionDataTable: INotifyPropertyChanged
{
private string _name;
/// <summary>
/// The <see cref="Name" /> property's name.
/// </summary>
private const string NamePropertyName = "Name";
public SubstitutionDataTable()
{
ColumnNames = new ObservableCollection<string>();
}
/// <summary>
/// Gets the Name property.
/// Changes to that property's value raise the PropertyChanged event.
/// </summary>
public string Name
{
get
{
return _name;
}
set
{
if (_name == value)
{
return;
}
_name = value;
RaisePropertyChanged(NamePropertyName);
}
}
public ObservableCollection<string> ColumnNames { get; set; }
#region Implementation of INotifyPropertyChanged
/// <summary>
/// A property has changed - update bindings
/// </summary>
[field: NonSerialized]
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
}
:以下のように定義SubstitutionDataTableで
namespace Lib
{
public class SubstitutionDataSet : DataSet
{
public SubstitutionDataSet()
{
TableNames = new ObservableCollection<SubstitutionDataTable>();
Tables.CollectionChanging += DataTablesCollectionChanging;
}
public ObservableCollection<SubstitutionDataTable> TableNames { get; set; }
private void DataTablesCollectionChanging(object sender, CollectionChangeEventArgs e)
{
var actionTable = (DataTable) e.Element;
if (e.Action == CollectionChangeAction.Add)
{
actionTable.Columns.CollectionChanged += DataColumnCollectionChanged;
TableNames.Add(new SubstitutionDataTable { Name = actionTable.TableName });
}
else if (e.Action == CollectionChangeAction.Remove)
{
actionTable.Columns.CollectionChanged -= DataColumnCollectionChanged;
TableNames.Remove(TableNames.First(tn => tn.Name == actionTable.TableName));
}
}
private void DataColumnCollectionChanged(object sender, CollectionChangeEventArgs e)
{
var actionColumn = (DataColumn) e.Element;
var hostTable = (DataTable) actionColumn.Table;
var hostSubsitutionTable = TableNames.First(tn => tn.Name == hostTable.TableName);
if (e.Action == CollectionChangeAction.Add)
{
hostSubsitutionTable.ColumnNames.Add(actionColumn.ColumnName);
}
else if (e.Action == CollectionChangeAction.Remove)
{
hostSubsitutionTable.ColumnNames.Remove(hostSubsitutionTable.ColumnNames.First(cn => cn == actionColumn.ColumnName));
}
}
}
}
:データセットから継承し、追加のコレクションを定義SubstituionDataSetクラス
...これがパズルの要点です...
上記のクラスは、DataSet内に新しいDataTableを定義し、列と行とランタイムを追加するために使用されます。私は、難読化プロセスの構成を可能にする別のクラスを持っています。構成の一部では、上で定義したSubstituionDataSetからDataTableとDataColumnを選択できます。
私は構成が有効であり、多くの難読化を構成してから構成をディスクにシリアル化できます。
GUIのバインディングに正しいDataTableとDataColumnの選択が表示されない場合、DataTableは完全修飾オブジェクト名を表示します。
現在、DataTableバインディングを取得しようとしています。私はDataColumnバインディングを再作成する必要があることを知っています。
GUI(ユーザーコントロール)は以下のように定義されます。
<UserControl xmlns:igEditors="http://infragistics.com/Editors" x:Class="SubstitutionOptions"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="421" d:DesignWidth="395">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="23" />
<RowDefinition Height="23" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150" />
<ColumnDefinition Width="20" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0"
Grid.Column="0"
Text="Dataset" />
<igEditors:XamComboEditor Grid.Row="0"
Grid.Column="2"
Name="tablesComboBox"
NullText="select a dataset..."
ItemsSource="{Binding DataContext.Project.SubstitutionDataSet.TableNames, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"
DisplayMemberPath="Name"
SelectedItem="{Binding DataContext.SelectedFieldSubstitutionDataTable, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"/>
<TextBlock Grid.Row="1"
Grid.Column="0"
Text="Column" />
<igEditors:XamComboEditor Grid.Row="1"
Grid.Column="2"
NullText="select a column..."
ItemsSource="{Binding DataContext.SelectedFieldSubstitutionDataTable.ColumnNames, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"
SelectedItem="{Binding DataColumn, Mode=TwoWay}"/>
</Grid>
</UserControl>
私は十分に問題を説明している願っています。現在のデザインを使用して作業する方法や、必要なものを達成するためにアプローチを再設計する方法について、誰かが考えていますか?
OK、返信はありません... 私は実際には、部分的に問題を回避してきました。 SubstitutionDataTableでequals演算子をオーバーライドしました。オブジェクトが逆シリアル化されると、コンボボックスのバインディングがほとんど動作します。 私が見る最初のフィールドは正しくバインドされていますが、別のフィールドをクリックするたびに最初に表示されたバインディングが保持されます... うーん、どんなアイデアですか? – Drammy