Wpf 当列表框中的任何一个组合框发生更改时,列表框中的所有组合框都会发生更改

Wpf 当列表框中的任何一个组合框发生更改时,列表框中的所有组合框都会发生更改,wpf,data-binding,combobox,listbox,Wpf,Data Binding,Combobox,Listbox,我在表单上有一个列表框,该表单绑定到自定义类型的可观察集合。在每个项目中,都有一个绑定到枚举类型的组合框。当窗口加载时,所有的组合框都默认为某个值。当我为任何一个(从UI,而不是从代码)更改SelectedItem时,所有其他ComboBoxe将更改为相同的SelectedItem 我不确定我做错了什么,这是我目前正在处理的XAML <Window.Resources> <ObjectDataProvider x:Key="SyncOperationValues"

我在表单上有一个
列表框
,该表单绑定到自定义类型的
可观察集合
。在每个项目中,都有一个绑定到枚举类型的
组合框。当窗口加载时,所有的组合框都默认为某个值。当我为任何一个(从UI,而不是从代码)更改
SelectedItem
时,所有其他
ComboBox
e将更改为相同的
SelectedItem

我不确定我做错了什么,这是我目前正在处理的XAML

<Window.Resources>
    <ObjectDataProvider x:Key="SyncOperationValues"
                        MethodName="GetNames"
                        ObjectType="{x:Type sys:Enum}">
        <ObjectDataProvider.MethodParameters>
            <x:Type TypeName="local:SyncOperationEnum" />
        </ObjectDataProvider.MethodParameters>
    </ObjectDataProvider>
...
    <DataTemplate x:Key="SyncListTemplate">
        <Grid Grid.Column="1" Grid.RowSpan="2" Margin="0,0,20,0" x:Name="olDetails"
            DataContext="{Binding Path=OlContact}">
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
            <RowDefinition />
            </Grid.RowDefinitions>
...
            <ComboBox x:Name="SyncOp" 
                Width="120" Height="19"
                Margin="4,0,10,0" 
                IsSynchronizedWithCurrentItem="True" 
                ItemsSource="{Binding Source={StaticResource SyncOperationValues}}"
                             SelectedItem="{Binding Operation}"
                             VerticalAlignment="Center" />

...
我尝试了一些不同的选项,比如绑定到
CollectionView
;然而,一切似乎都不起作用。有人能指出我的错误吗

谢谢

看起来您的“操作”属性应该是静态属性。因为当您更改它时,它会绑定到每个组合框, 因此,XAML中的其他所有内容都是正确的,只需将属性设置为bellow

    static SyncOperationEnum _operation;

    public static SyncOperationEnum Operation
    {
        get { return _operation; }
        set { _operation = value;}
    }

我遇到了与此类似的情况,并将组合框上的IsSynchronizedWithCurrentItem属性设置为“False”修复了它。按照我的理解,将值设置为“True”意味着ComboBox值将是ListBox当前项的同步值。基本上,所有组合框都绑定到相同的值。听起来这就是你正在经历的。尝试:

IsSynchronizedWithCurrentItem="False"

我终于找到了解决办法。最后我为枚举类型编写了一个ValueConverter。我一直认为这是不必要的,但出于某种原因,至少如果ComboBox位于另一个某种列表(在我的例子中是ListBox)中,它是必要的

正如John M建议的那样,我确实需要将IsSynchronizedWithCurrentItem属性设置为false,所以感谢John!下面是转换器代码,以防其他人需要这样做

[ValueConversion( typeof( SyncOperationEnum ), typeof( String ) )]
public class SyncOperationConverter : IValueConverter {
    #region IValueConverter Members

    public object Convert( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture ) {
        if( value != null && value.GetType() == typeof( SyncOperationEnum ) )
            return Enum.GetName( typeof( SyncOperationEnum ), value );

        return null;
    }

    public object ConvertBack( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture ) {
        if( value != null && targetType == typeof( SyncOperationEnum ) )
            foreach( object enumValue in Enum.GetValues( targetType ) )
                if( value.Equals( Enum.GetName( targetType, enumValue ) ) )
                    return enumValue;

        return null;
    }

    #endregion
我的XAML现在看起来像这样:

<Window.Resources>
    <local:SyncOperationConverter x:Key="SyncConverter" />

    <ObjectDataProvider x:Key="SyncOperationValues"
                    MethodName="GetNames"
                    ObjectType="{x:Type sys:Enum}">
        <ObjectDataProvider.MethodParameters>
            <x:Type TypeName="local:SyncOperationEnum" />
        </ObjectDataProvider.MethodParameters>
    </ObjectDataProvider>
...
<DataTemplate x:Key="SyncListTemplate">
    <Grid Grid.Column="1" Grid.RowSpan="2" Margin="0,0,20,0" x:Name="olDetails"
        DataContext="{Binding Path=OlContact}">
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
        <RowDefinition />
        </Grid.RowDefinitions>
...
        <ComboBox x:Name="SyncOp" 
            Width="120" Height="19"
            Margin="4,0,10,0" 
            IsSynchronizedWithCurrentItem="False" 
            ItemsSource="{Binding Source={StaticResource SyncOperationValues}}"
            SelectedValue="{Binding Path=Operation,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged,Converter={StaticResource SyncConverter}}"
            VerticalAlignment="Center" />

...
...

“操作”是列表框绑定到的对象上的实例属性。如果我将其更改为static,我只会得到一个编译器错误,因为它不是实例属性,所以无法访问。我应该注意-ListBox绑定到一个ObservableCollecton对象,每个对象都包含Operation属性。这更接近。我验证了将其设置为False可以修复问题;但是,我将其设置为“True”的原因是,当窗口第一次出现时,所有组合框都没有选择的值,而不是它们绑定到的“Operation”属性的值。尝试绑定到组合框上的SelectedValue而不是SelectedItem只是尝试了一下,没有解决问题。仍然没有选择任何内容。
<Window.Resources>
    <local:SyncOperationConverter x:Key="SyncConverter" />

    <ObjectDataProvider x:Key="SyncOperationValues"
                    MethodName="GetNames"
                    ObjectType="{x:Type sys:Enum}">
        <ObjectDataProvider.MethodParameters>
            <x:Type TypeName="local:SyncOperationEnum" />
        </ObjectDataProvider.MethodParameters>
    </ObjectDataProvider>
...
<DataTemplate x:Key="SyncListTemplate">
    <Grid Grid.Column="1" Grid.RowSpan="2" Margin="0,0,20,0" x:Name="olDetails"
        DataContext="{Binding Path=OlContact}">
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
        <RowDefinition />
        </Grid.RowDefinitions>
...
        <ComboBox x:Name="SyncOp" 
            Width="120" Height="19"
            Margin="4,0,10,0" 
            IsSynchronizedWithCurrentItem="False" 
            ItemsSource="{Binding Source={StaticResource SyncOperationValues}}"
            SelectedValue="{Binding Path=Operation,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged,Converter={StaticResource SyncConverter}}"
            VerticalAlignment="Center" />