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。现在我什至可以接受这样一个事实,即下拉列表中的项目只是被禁用,如果它使事情变得更容易的话,我只需要这样一个事实,即如果他已经被选中,它就不能再次被选中
要求:
- 多个组合框都显示同一组选项。
- 如果在组合框中选择了某个项目,则可能不会在任何 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>
组合框。我遗漏了您拥有的一些属性。对于我添加到您的代码中重要的是 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
getter 返回 !selezionato
-- 可能是打字错误,但如果不是,那就是个坏主意!
public bool Selezionato
{
get { return selezionato; }
set
{
if (selezionato != value)
{
selezionato = value;
OnPropertyChanged("Selezionato");
}
}
}
我知道这个话题已经有人回答了,但我无法用我找到的解决方案解决问题。所以这是我的代码:
<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。现在我什至可以接受这样一个事实,即下拉列表中的项目只是被禁用,如果它使事情变得更容易的话,我只需要这样一个事实,即如果他已经被选中,它就不能再次被选中
要求:
- 多个组合框都显示同一组选项。
- 如果在组合框中选择了某个项目,则可能不会在任何 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>
组合框。我遗漏了您拥有的一些属性。对于我添加到您的代码中重要的是 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
getter 返回 !selezionato
-- 可能是打字错误,但如果不是,那就是个坏主意!
public bool Selezionato
{
get { return selezionato; }
set
{
if (selezionato != value)
{
selezionato = value;
OnPropertyChanged("Selezionato");
}
}
}