我有一个ViewModel,其ObservableCollection<MyData> MainCollection
和MyData SelectedData
保存MainCollection中当前选定的项目。 MyData
由多个属性和ObservableCollection<MyValuePair> MyPairs
组成。 MyValuePair
由2个属性Description
和Value
组成,就像KeyValuePair一样(不能使用字典,因为我想要使用TwoWay绑定)。
我希望根据我的DataTemplate动态创建foreach MyValuePair
的控件(我试着像这里一样:Adding controls dynamically in WPF MVVM):
//do not want to create another viewModel
<DataTemplate DataType="{x:Type vm:MyValuePairViewModel }">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
//problem can only select one MyValuePair at a time
<TextBlock Text="{Binding MyValuePair.Description, Mode=TwoWay}"/>
<TextBox Template="{StaticResource TextBoxBaseControlTemplate}" Grid.Row="0" Grid.Column="1" Text="{Binding MyValuePair.Value, Mode=TwoWay}"/>
</Grid>
</DataTemplate>
迈德特:
public class MyData
{
//Properties
ObservableCollection<MyValuePair> MyPairs { get; set; }
}
MainViewModel:
public class MainViewModel : ViewModelBase
{
ObservableCollection<MyData> MainCollection { get; set; }
MyData selectedData
public MyData SelectedData
{
get { return selectedData; }
set
{
Set(() => SelectedData, ref selectedData, value);
}
}
}
MyValuePair:
public class MyValuePair
{
private string description;
public string Description
{
get { return description; }
set { description = value; }
}
private string _value;
public string Value
{
get { return _value; }
set { _value = value; }
}
但问题是我不想为我的MyValuePair
创建另一个ViewModel(MyValuePairViewModel),因为每次SelectedData更改或MyPair(MyValuePair类型)更改时我都必须将其与MainViewModel同步必须将它同步回MainViewModel并且感觉不对。
那么有一种简单的方法可以将我的DataTemplate直接绑定到SelectedData中ObservableCollection<MyValuePair>
属性中的每个元素,以便为每个MyPairs创建DataTemplate吗?
修改 目前我正在使用另一个ViewModel:
public class MyValuePairViewModel : ViewModelBase
{
private MyValuePair myValuePair;
public MyValuePair MyValuePair
{
get { return myPair; }
set
{
Set(() => MyValuePair, ref myValuePair, value);
}
}
public MyValuePairViewModel(MyValuePair myValuePair)
{
MyValuePair = myValuePair;
}
}
并将其添加到我的MainViewModel中,如下所示:
public ObservableCollection<MyValuePairViewModel> MyPairs { get; set; }
。
因此,对于MyPairs中的每个元素,我创建了上面的DataTemplate
每当选择ListView更改时,我都会执行以下操作:
public void RefreshKeyValuePairs()
{
if (MyPairs != null)
{
MyPairs.Clear();
}
if (SelectedData != null)
{
foreach (MyValuePair item in SelectedData.MyPairs)
{
MyValuePairViewModel vm = new MyValuePairViewModel(item);
MyPairs.Add(vm);
}
}
}
但是,在这种情况下,每当我在创建的TextBox中键入内容时,它都不会在MyValuePairViewModel内部的MainViewModel的SelectedData内部更新,我必须在MyValuePairViewModel Set方法中手动将其同步到MainViewModel&#39; s SelectedData(但这也要求我在MyValuePairViewModel中有MainViewModel的实例)。
换句话说,我想直接绑定到创建的元素SelectedData.MyPairs[0].Description
绑定到第一个创建的TextBlock,SelectedData.MyPairs[1].Description
绑定到第二个创建的TextBlock,依此类推,以便它自动在两个方向上更新。如果SelectedData.MyPairs
不是集合而是普通属性,我可以直接绑定它。
答案 0 :(得分:1)
您可以将UI元素直接绑定到MyValuePair对象。您不需要特定的ViewModel类MyValuePairViewModel。
您唯一想念的是在MyValuePair上实现INotifyPropertyChanged。 UI将正常初始化,但初始化后对Description和Value属性的编程更新不会出现在UI中。 如果您不进行任何程序化更新,这将不会成为问题。
如果要对Description和Value属性进行更改,最简单的方法是直接在MyValuePair上实现INotifyPropertyChanged。 这只需要几行代码,并且比使用单独的类MyValuePairViewModel复制功能更容易。