![](/img/trans.png)
[英]Binding of event in DataTemplate of WPF's TabItem's WebBrowser, MVVM
[英]WPF MVVM Binding collection to DataTemplate
我有一个ViewModel,它具有一个ObservableCollection<MyData> MainCollection
和MyData SelectedData
,其中包含从MainCollection当前选择的项目。 MyData
包含多个属性,还包含ObservableCollection<MyValuePair> MyPairs
。 MyValuePair
由2个属性Description
和Value
组成,就像KeyValuePair一样(无法使用字典,因为我想具有TwoWay绑定)。
我想根据我的DataTemplate动态地为每个MyValuePair
创建控件(我正在尝试这样做: 在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; }
}
但问题是我不想为我创建另一个视图模型(MyValuePairViewModel) MyValuePair
,因为那时我已经把它与我的MainViewModel每次的SelectedData改变或者如果MyPair(类型MyValuePair)的同步变化我必须把它同步回MainViewModel,感觉不对。
那么,是否有一种简单的方法可以将我的DataTemplate直接绑定到SelectedData中ObservableCollection<MyValuePair>
属性内的每个元素,以便为每个MyPair创建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; }
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中键入内容时,它都不会在MainViewModel的SelectedData中仅在MyValuePairViewModel内更新,并且我必须在MyValuePairViewModel Set方法内手动将其同步到MainViewModel的SelectedData(但这还要求我拥有实例在MyValuePairViewModel内部的MainViewModel)。
换句话说,我想直接绑定到创建的元素SelectedData.MyPairs[0].Description
绑定到第一个创建的TextBlock, SelectedData.MyPairs[1].Description
绑定到第二个创建的TextBlock,依此类推,以便它自动在两个方向上更新。 如果SelectedData.MyPairs
不是集合,而是普通属性,则可以直接绑定到它。
您可以将UI元素直接绑定到MyValuePair对象。 您不需要特定的ViewModel类MyValuePairViewModel。
您唯一会错过的是MyValuePair上INotifyPropertyChanged的实现。 UI将正常初始化,但是初始化后对Description和Value属性的编程更新将不会出现在UI中。 如果您不进行任何程序更新,这将不是问题。
如果要更改Description和Value属性,最简单的方法是直接在MyValuePair上实现INotifyPropertyChanged。 这仅需要几行代码,并且比使用单独的类MyValuePairViewModel复制功能要容易。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.