Все комбинированные списки в ListBox изменяются при изменении любого из них. - PullRequest
4 голосов
/ 06 февраля 2009

У меня есть ListBox в форме, связанной с ObservableCollection пользовательского типа. Внутри каждого элемента есть ComboBox, связанный с типом перечисления. Когда окно загружается, все ComboBox по умолчанию имеют определенное значение. Когда я изменяю SelectedItem для любого (из интерфейса, а не из кода), все остальные ComboBox меняются на те же 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" />

...

и ListBox:

 <ListBox x:Name="SyncList"
     ScrollViewer.HorizontalScrollBarVisibility="Hidden"
     ItemContainerStyle="{StaticResource StretchedContainerStyle}"
     ItemTemplate="{StaticResource SyncListTemplate}">
 ListBox>

Я пробовал несколько разных вариантов, например привязку к CollectionView; Однако, похоже, ничего не работает. Кто-нибудь может указать мне на мою ошибку?

Спасибо!

Ответы [ 3 ]

7 голосов
/ 07 февраля 2009

У меня была ситуация, подобная этой, и установка свойства IsSynchronizedWithCurrentItem в ComboBox на «False» исправила его. Насколько я понимаю, установка значения «True» означает, что значение ComboBox будет синхронизированным значением текущего элемента для ListBox. По сути, все ComboBox связаны с одним и тем же значением. Похоже, это то, что вы испытываете. Попробуйте:

IsSynchronizedWithCurrentItem="False"
4 голосов
/ 09 февраля 2009

Я наконец нашел решение. Я закончил тем, что написал ValueConverter для типа перечисления. У меня сложилось впечатление, что в этом нет необходимости, но по какой-то причине, по крайней мере, если ComboBox находится в другом списке (ListBox в моем случае) какого-то рода.

Мне нужно было установить для свойства IsSynchronizedWithCurrentItem значение false, как предложил Джон М, так что спасибо Джону за это! Вот код конвертера на случай, если кому-то еще понадобится что-то подобное.

[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" />
0 голосов
/ 06 февраля 2009

Похоже, что ваше свойство "Operation" должно быть статическим. Поскольку он связывается с каждым ComboBox при его изменении, Так что все остальное прямо в вашем XAML, просто сделайте свойство как ниже

    static SyncOperationEnum _operation;

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