Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 多值转换器-NotifyPropertyChanged_C#_Wpf_Datagrid_Combobox_Multibinding - Fatal编程技术网

C# 多值转换器-NotifyPropertyChanged

C# 多值转换器-NotifyPropertyChanged,c#,wpf,datagrid,combobox,multibinding,C#,Wpf,Datagrid,Combobox,Multibinding,我的要求有点烦人,希望能解决 假设您有以下类: 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

我的要求有点烦人,希望能解决

假设您有以下类:

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; }
}
这两个属性绑定到相应的组合框:

<c1:C1ComboBox ItemsSource="{Binding Id1s}"
                SelectedItem="{Binding SelectedId1}" />
<c1:C1ComboBox ItemsSource="{Binding Id2s}"
                SelectedItem="{Binding SelectedId2}" />
现在这工作得很好,甚至当我在UI中更改2个组合框中的值并相应地更新信息时,它的行为都是正确的,但是。。。当基础Sum PropertyChanges发生更改并且收到PropertyChanges通知时,UI不会更新

如果我把这根柱子绑在墙上就行了

<DataGridTextColumn Binding="{Binding FooBs[12].Sum}" />

你可以想象我不想在那里有一个索引,因为我需要通过UI中的组合框来更新它


希望您能帮助我。

首先,我很难理解您当前的绑定表达式实际上是如何表示和的,因为您的转换器似乎只是返回FooB对象本身,而不是它的sum属性-因此,除非在FooB类上有一个特定的ToString()实现来格式化它以显示sum,否则我完全不知所措

其次,我认为您的问题源于这样一个事实,即您的多绑定仅基于两个属性-数据。因此,除非这两个属性中的任何一个发生变化,多重绑定不会收到属性更改事件和更新

结果的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(尝试动态设置绑定的源):



是的,你是对的,我没有在我的示例中提供有关如何获得
Sum
属性的信息,对此表示抱歉。在我的实际应用程序中,我尝试了两种方法,使用
.ToString()
和在转换器中传递
.Sum
属性,这两种方法都没有您已经解释过的运气。你是说我需要为
Foo
提供
CurrentFooB
属性,并用正确的
FooB
更新网格中的所有实例?我有点希望有一种方法,可以通过绑定中的源属性获取对象,或者我不知道。。。只需指定求和的路径。或者在一个绑定中有一个多绑定,这样每个mutlibinding都可以绑定源/数据上下文以获得正确的FooB,而绑定本身只指定路径。。。一些内置WPF/XAML的东西没有代码隐藏。是的,我知道你的担心,我相信一定有办法。从我的头顶上。。。嗯。。如果您可以使用当前的多重绑定来设置另一个仅绑定到Sum属性的绑定的DataContext呢?这样就可以了,不是吗?由于DataContext将是FooB的实例和,并且绑定将提供DataContext的路径,因此在收到有关propertychanged的Sum通知时采用这种方式。底层数据绑定将检查“嘿,我的DataContext是FooB,我的路径是Sum so update”,但这只是胡思乱想,因为没有嵌套绑定-->多重绑定。类似于
。或者与
相同,我希望如此!:P检查我编辑的答案,我刚刚意识到使用绑定的Source属性可能比使用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();
    }
}
<DataGridTextColumn Binding="{Binding FooBs[12].Sum}" />
<DataGrid ItemsSource={Binding Foos}>

    <DataGrid.Columns>

        <DataGridTextColumn Binding="{Binding Name}"/>
        <DataGridTextColumn Binding="{Binding CurrentFooB.Sum}"/>

    </DataGrid.Columns>

</DataGrid>
<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>