对我的要求有一点恼人的问题,希望有可能解决。
让我们假设您有以下类:
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
类的FooB
列表包含Id1
和Id2
个值以及Sum
值。
在我的WPF用户界面中,我有2 ComboBoxes
和1 DataGrid
。
1 ComboBox包含有关Id1
和其他Id2
的信息。
现在在我的DataGrid中,我有一个显示为Foo
的列表,其中2列显然是名称,但另一个让我头疼。
第二列应显示Sum
类的"correct" FooB
属性。
正确的FooB类由UI中的2个ComboBox和SelectedItem决定。
到目前为止我所做的是在我的CodeBehind中创建2个属性:(注意他们实际上有后台和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中的Window获取数据)
转换器看起来像这样:
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();
}
}
现在效果非常好,当我更改UI中的2个ComboBox中的值并相应地更新信息时,即使行为也正确但是......当底层Sum PropertyChanges并且得到PropertyChanges的通知时,UI不会更新。
如果我将列绑定到
,它的工作正常<DataGridTextColumn Binding="{Binding FooBs[12].Sum}" />
你可以想象我不想在那里有索引,因为我需要通过UI中的ComboBox来更新它。
希望你能帮助我。
答案 0 :(得分:2)
首先,我很难理解你当前的绑定表达式实际上是如何呈现总和,因为转换器似乎只返回 FooB < / strong>对象本身,而不是 sum 属性 - 所以除非你在 FooB 类上有一个特定的 ToString()实现,格式化它以显示总和,我完全迷失了。
其次,我认为您的问题源于您的 MultiBinding 仅基于两个属性 - Data.SelectedId1 和 Data.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 的总和发生变化时,您的视图就会更新。
编辑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>