WPF:如何更改我的组合框项目的可见性?

WPF: How to change the visibility of my ComboBox Items?

我知道这个话题已经有人回答了,但我无法用我找到的解决方案解决问题。所以这是我的代码:

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

简而言之,我有一个绑定到数据表的自定义数据网格。每列的 header 是一个组合框,其来源是此 class 的可观察 collection:

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 也不同步,因此它根本无法按预期工作。

编辑:这是 collection

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

编辑 2:我的要求是,如果在 N 组合框中的任何一个组合框中选择了一个项目,那么任何人都不能选择该项目,直到他失去 SelectedItem 状态。例如,假设我有 2 个组合框和一个 collection 的 4 个 Item (x,y,a,b) 。如果在 ComboBox1 中选择了 x,则在 ComboBox1 的 SelectedItem 更改(例如从 x 更改为 y)之前,无法在 2 ComboBox 的 none 中选择 x。现在我什至可以接受这样一个事实,即下拉列表中的项目只是被禁用,如果它使事情变得更容易的话,我只需要这样一个事实,即如果他已经被选中,它就不能再次被选中

要求:

  1. 多个组合框都显示同一组选项。
  2. 如果在组合框中选择了某个项目,则可能不会在任何 other 组合框中选择它。

我们将在组合框的 ItemContainerStyle 中使用触发器隐藏和禁用,由组合框项目的 bool Selezionato 属性 驱动。我们更喜欢在样式中也使用 Binding 设置 Selezionato,但我发现它有时会在我不希望它取消选择项目时取消选择,所以我在 [= =18=] 处理程序代替。

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

组合框。我遗漏了您拥有的一些属性。对于我添加到您的代码中重要的是 ItemContainerStyleSelectionChanged:

<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 getter 返回 !selezionato -- 可能是打字错误,但如果不是,那就是个坏主意!

public bool Selezionato
{
    get { return selezionato; }
    set
    {
        if (selezionato != value)
        {
            selezionato = value;
            OnPropertyChanged("Selezionato");
        }
    }
}