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 ответ
Требования:
- Несколько комбинированных полей отображают один и тот же набор параметров.
- Если элемент выбран в поле со списком, он не может быть выбран в любом другом поле со списком.
Мы сделаем скрытие и отключение с помощью триггеров в 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");
}
}
}