【发布时间】:2018-04-06 15:39:05
【问题描述】:
我有一个 ViewModel,它有一个 ObservableCollection<MyData> MainCollection 和 MyData SelectedData,其中包含 MainCollection 中当前选定的项目。 MyData 由几个属性和一个ObservableCollection<MyValuePair> MyPairs 组成。 MyValuePair 由 2 个属性 Description 和 Value 组成,就像 KeyValuePair 一样(不能使用字典,因为我想要双向绑定)。
我想根据我的 DataTemplate 为每个 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; }
}
主视图模型:
public class MainViewModel : ViewModelBase
{
ObservableCollection<MyData> MainCollection { get; set; }
MyData selectedData
public MyData SelectedData
{
get { return selectedData; }
set
{
Set(() => SelectedData, ref selectedData, value);
}
}
}
我的值对:
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 的 SelectedData(但这也需要我在 MyValuePairViewModel 中有 MainViewModel 的实例)。
换句话说,我想直接绑定到创建的元素 SelectedData.MyPairs[0].Description 绑定到第一个创建的 TextBlock,SelectedData.MyPairs[1].Description 绑定到第二个创建的 TextBlock 等等,以便它在两个方向上自动更新。如果SelectedData.MyPairs 不是集合而是普通属性,我可以直接绑定到它。
【问题讨论】:
-
我并没有真正理解这个问题。使用类似这样的列表框将每个项目模板化到您的 itemtemplate 中的控件中。也许答案是使用当前项绑定 / 并在列表框上设置 IsSynchronizedWithCurrentItem true。绑定到 observablecollection 的默认视图。
-
我认为您应该更改数据模板中的绑定。使用描述代替 SelectedData.MyPairs.Description,并对 Value 属性执行相同操作
-
@Andy 试图澄清一下。
-
WPF 博士构建了一种称为可观察字典的东西。我认为这确实有两种方式。我已经有一段时间没有使用了。 drwpf.com/blog/2007/09/16/can-i-bind-my-itemscontrol-to-a-dictionary/
标签: c# wpf mvvm binding observablecollection