WPF: Как изменить видимость элементов ComboBox?

Я знаю, что на эту тему уже дан ответ, но я не мог решить проблему с решением, которое я нашел. Итак, вот мой код:

<DataGrid HeadersVisibility="Column" Name="griglia" Grid.Row="2" ItemsSource="{Binding Path=Test}" AutoGenerateColumns="True" IsReadOnly="True" ScrollViewer.CanContentScroll="True" ScrollViewer.VerticalScrollBarVisibility="Visible" ScrollViewer.HorizontalScrollBarVisibility="Visible">
        <DataGrid.ColumnHeaderStyle>
            <Style TargetType="{x:Type DataGridColumnHeader}">
                <Setter Property="ContentTemplate" >
                    <Setter.Value>
                        <DataTemplate DataType="DataGridColumnHeader"  >
                            <ComboBox SelectedValue="{Binding Selezione}" SelectedValuePath="Selezionato" Width="100" Height="20" ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}},Path=DataContext.Selezione}"  SelectionChanged="Test_SelectionChanged">
                                <ComboBox.ItemTemplate>
                                    <DataTemplate >
                                        <TextBlock Text="{Binding Path=Oggetto}"/>
                                    </DataTemplate>
                                </ComboBox.ItemTemplate>
                            </ComboBox>
                        </DataTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </DataGrid.ColumnHeaderStyle>
    </DataGrid>

В нескольких словах у меня есть пользовательская сетка данных, которая связана с таблицей данных. Заголовок каждого столбца представляет собой комбинированный список, источником которого является наблюдаемая коллекция этого класса:

public class PopolazioneCombo 
{
    public string Oggetto { get; set; }
    private bool selezionato = false;
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propName)
    {
        var handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propName));
        }
    }
    public bool Selezionato
    {
        get { return !selezionato; }
        set
        {
            if(selezionato != value)
            {
                selezionato = value;
                OnPropertyChanged("Selezionato");
            }
        }
    }
}

Моя проблема заключается в следующем: мне нужно изменить видимость каждого выбранного элемента, чтобы он свернулся во всех выпадающих списках (поскольку они имеют один и тот же источник). Я попытался создать собственное событие SelectionChanged, в котором я изменил значение "Selezionato" и ограничил видимость текстового блока следующим образом:

<TextBlock Text="{Binding Path=Oggetto}" Visibility="{Binding Path=Selezionato, Converter={StaticResource BoolToVis}, UpdateSourceTrigger=PropertyChanged}"/>

Проблема в том, что мой SelectedItem не только не отображается в выпадающем списке, но и ComoBoxItem не синхронизируется, поэтому он не работает вообще, как предполагалось.

РЕДАКТИРОВАТЬ: это коллекция

 public ObservableCollection<PopolazioneCombo> Selezione
    {
        get
        {
            return selezione;
        }
        set
        {
            if (selezione != value)
            {
                selezione = value;
                OnPropertyChanged("Selezione");
            }
        }
    }

РЕДАКТИРОВАТЬ 2: Мое требование заключается в том, что, если в любом из выпадающего списка N выбран элемент, то этот элемент не может быть выбран никем, пока он не потеряет статус SelectedItem. Например, давайте предположим, что у меня есть 2 комбинированных списка и коллекция из 4 элементов (x,y,a,b) . Если x выбран в ComboBox1, то x не может быть выбран ни в одном из 2 ComboBox, пока SelectedItem ComboBox1 не изменится (например, с x на y). Теперь я могу даже принять тот факт, что элемент в раскрывающемся списке просто отключен, если он делает вещи проще, мне просто нужен факт, что его нельзя выбрать снова, если он уже выбран

1 ответ

Решение

Требования:

  1. Несколько комбинированных полей отображают один и тот же набор параметров.
  2. Если элемент выбран в поле со списком, он не может быть выбран в любом другом поле со списком.

Мы сделаем скрытие и отключение с помощью триггеров в ItemContainerStyle на выпадающих списках, управляемых bool Selezionato свойство элементов комбинированного списка. Мы бы предпочли установить Selezionato с Binding в том же стиле, но я обнаружил, что иногда отменял выбор элементов, когда я не хотел этого, поэтому я сделал это в ComboBox.SelectionChanged обработчик вместо.

<Style 
    x:Key="SingleSelectionComboBoxItem" 
    TargetType="ComboBoxItem" 
    BasedOn="{StaticResource {x:Type ComboBoxItem}}"
    >
    <!-- This unselects sometimes when you don't want it to. -->
    <!--
    <Setter Property="IsSelected" Value="{Binding Selezionato, Mode=OneWayToSource}" />
    -->
    <Style.Triggers>
        <DataTrigger Binding="{Binding Selezionato}" Value="True">
            <!-- Hide it -->
            <Setter Property="Visibility" Value="Collapsed" />
            <!-- Also prevent user from selecting it via arrows or mousewheel -->
            <Setter Property="IsEnabled" Value="False" />
        </DataTrigger>
    </Style.Triggers>
</Style>

ComboBoxes. Я оставляю некоторые из свойств, которые вы имели. Что важно для моего добавления в ваш код ItemContainerStyle а также SelectionChanged:

<ComboBox
    ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=DataContext.Selezione}" 
    DisplayMemberPath="Oggetto"
    ItemContainerStyle="{StaticResource SingleSelectionComboBoxItem}"
    SelectionChanged="SingleSelectionComboBox_SelectionChanged"
    />

Код позади:

private void SingleSelectionComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    foreach (var item in e.RemovedItems.OfType<PopolazioneCombo>())
    {
        item.Selezionato = false;
    }

    foreach (var item in e.AddedItems.OfType<PopolazioneCombo>())
    {
        item.Selezionato = true;
    }
}

Еще одна вещь, которую я заметил по пути:

Вы имели PopolazioneCombo.Selezionato возвращение добытчика !selezionato - возможно опечатка, но если нет, плохая идея!

public bool Selezionato
{
    get { return selezionato; }
    set
    {
        if (selezionato != value)
        {
            selezionato = value;
            OnPropertyChanged("Selezionato");
        }
    }
}
Другие вопросы по тегам