我的要求有点小问题,希望能解决。
让我们假设你有以下类:
public class Foo
{
public string Name { get; set; }
public List<FooB> FooBs { get; set; }
}
public class FooB
{
public int Id1 { get; set; }
public int Id2 { get; set; }
public decimal Sum { get; set; }
}
现在Foo
类具有给定Id1
和Id2
值的FooB
列表和计算出的Sum
值。
在我的WPF用户界面,我有2 ComboBoxes
和1 DataGrid
。1 . ComboBox保存Id1
和Id2
的信息。
现在在我的DataGrid中,我有一个Foo
列表,显示2列,其中一列显然是名称,但另一列现在让我头痛。
第二列应该显示"correct" FooB
类的Sum
属性。
正确的FooB类是由UI中的2个combobox和SelectedItem决定的。
到目前为止,我所做的是在我的CodeBehind中创建2个属性:(注意它们实际上有backingfields和PropertyChanged指定,我将代码减少到我的主要问题)
public int SelectedId1 { get; set; }
public int SelectedId2 { get; set; }
这两个属性被绑定到相应的ComboBox:
<c1:C1ComboBox ItemsSource="{Binding Id1s}"
SelectedItem="{Binding SelectedId1}" />
<c1:C1ComboBox ItemsSource="{Binding Id2s}"
SelectedItem="{Binding SelectedId2}" />
我的DataGrid到目前为止是这样的:
<local:BindingProxy x:Key="BindingProxy"
Data="{Binding}" />
<DataGrid ItemsSource={Bindings Foos}>
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Name}" />
<DataGridTextColumn>
<DataGridTextColumn.Binding>
<MultiBinding Converter="{StaticResource GetCorrectFooB}">
<Binding Binding="."></Binding>
<Binding Binding="Data.SelectedId1"></Binding>
<Binding Binding="Data.SelectedId2"></Binding>
</MultiBinding>
</DataGridTextColumn.Binding>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
(注意BindingProxy是从这里:http://www.thomaslevesque.com/2011/03/21/wpf-how-to-bind-to-data-when-the-datacontext-is-not-inherited/-启用从窗口的DataGridRow的DataContext中获取数据)
转换器看起来像这样:
public class GetCorrectFooB : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
var foo = (Foo)values[0];
var id1 = (int) values[1];
var id2 = (int) values[2];
return foo.FooBs.First(x => x.Id1 == id1 && x.Id2 == id2).Sum;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
这工作得很好,现在,甚至行为正确,当我改变值在2组合框在UI和更新相应的信息,但是…当底层的Sum PropertyChanges发生变化,并且得到PropertyChanges的通知时,UI不会更新。
如果我将列绑定到
,它会工作得很好<DataGridTextColumn Binding="{Binding FooBs[12].Sum}" />
你可以想象,我不想在那里有一个索引,因为我需要通过UI中的组合框来更新它。
希望你能帮助我。
首先,我正在努力理解你当前的绑定表达式实际上是如何呈现sum,因为你的转换器似乎只是返回FooB对象本身,而不是它的sum属性-所以除非你有一个特定的ToString()实现在你的FooB类格式化它来呈现sum,我完全丢失了。
其次,我认为你的问题源于这样一个事实,即你的MultiBinding仅基于两个属性- Data。SelectedId1 and 数据。SelectedId2,因此,除非这两个属性中的任何一个改变,否则MultiBinding将不会收到PropertyChanged事件和更新。更改结果的sum属性的值不是这两个,所以这很可能是视图没有更新的原因。
我绞尽脑汁作为解决这个问题的最好方法,也许你应该在ViewModel中处理这个问题,有一个名为CurrentFooB的属性或你可以绑定到的东西。然后将该值设置为组合框的SelectionChanged事件处理程序中相应的FooB实例。
你的绑定看起来像这样:
<DataGrid ItemsSource={Binding Foos}>
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Name}"/>
<DataGridTextColumn Binding="{Binding CurrentFooB.Sum}"/>
</DataGrid.Columns>
</DataGrid>
现在,假设FooB实现了INotifyPropertyChanged,当当前找到的FooB的sum变化时,您的视图应该更新。
EDIT 1(尝试动态设置绑定源):
<DataGrid ItemsSource={Binding Foos}>
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Name}"/>
<DataGridTextColumn>
<DataGridTextColumn.Binding>
<Binding Path="Sum">
<Binding.Source>
<MultiBinding Converter="{StaticResource GetCorrectFooB}">
<Binding Binding="."></Binding>
<Binding Binding="Data.SelectedId1"></Binding>
<Binding Binding="Data.SelectedId2"></Binding>
</MultiBinding>
</Binding.Source>
</Binding>
</DataGridTextColumn.Binding>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>