WPF скрыть элемент Combobox ItemSource - PullRequest
0 голосов
/ 20 февраля 2020

В моем WPF View у меня есть DataGrid, который отображает данные из базы данных. Один столбец - это поле со списком, которое привязано к строке в базе данных.

Это список доступных строк:

public List<string> AvailableTypeImpression { get; } = new List<string>() {"S","D","T","X","M","p","P","R"}

Все эти строки могут отображаться в сетке данных, но если Пользователь хочет отредактировать его, я могу установить только S, D, T или X. Пользователю не разрешено устанавливать M, p, P или R.

Поэтому я хотел бы скрыть эти четыре буквы от В выпадающем списке доступных предметов. Но я не знаю, как это сделать простым способом (я нашел какое-то решение по переполнению стека, но в моем случае это не работает).

Вот код моей таблицы данных:

<DataGrid Grid.Row="1" x:Name="LotsListDataGrid" IsReadOnly="False" SelectionMode="Single" SelectionUnit="FullRow" SelectedItem="{Binding SelectedLot}" ItemsSource="{Binding FilteredList}"  VirtualizingPanel.IsVirtualizing="True" EnableRowVirtualization="True" HorizontalScrollBarVisibility="Auto">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Lot" Width="200" Binding="{Binding Value.Lot.Intitule}" IsReadOnly="True"/>

        <DataGridTemplateColumn Header=".i." HeaderStyle="{StaticResource CenteredColumnHeaderStyle}" Width="545" IsReadOnly="False">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <ComboBox Height="23" Style="{StaticResource AnfComboBoxStyle}" ItemsSource="{Binding DataContext.AvailableTypeImpression, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}" SelectedItem="{Binding Value.Lot.TypeImpression, UpdateSourceTrigger=PropertyChanged}">
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

FilteredList.Value.Lot.TypeImpression является строкой.

Если я хорошо понял, все возможные строки должны быть в ItemSource, иначе они не могли бы отображаться. Но мне нужно найти способ запретить пользователю выбирать некоторые из них.

Спасибо за вашу помощь.

Ответы [ 2 ]

0 голосов
/ 21 февраля 2020

Решение от @dheller было хорошим, но не работало в моем случае, потому что пользователь не может дать «Value.Lot.TypeImpression» новое значение M, p, P или R, но он может редактировать «значение .Lot.TypeImpression ", даже если он равен M, p, P или R и установлен S, D, T или X.

Итак, я нашел другой способ:

В моем ViewModel Я определил новый класс:

public class TypeImpressionAvailable
{
    public string Name { get; set; }
    public bool IsAvailable { get; set; }
}

И мой список, чтобы дать моему списку, как ItemSource:

public List<TypeImpressionAvailable> AvailableTypeImpression { get; } = new   List<TypeImpressionAvailable>() {
new TypeImpressionAvailable(){ Name="N", IsAvailable=true },
new TypeImpressionAvailable(){ Name="S", IsAvailable=true },
new TypeImpressionAvailable(){ Name="D", IsAvailable=true },
new TypeImpressionAvailable(){ Name="T", IsAvailable=true },
new TypeImpressionAvailable(){ Name="X", IsAvailable=true },
new TypeImpressionAvailable(){ Name="M", IsAvailable=false },
new TypeImpressionAvailable(){ Name="p", IsAvailable=false },
new TypeImpressionAvailable(){ Name="P", IsAvailable=false },
new TypeImpressionAvailable(){ Name="R", IsAvailable=false }
};

И в моем представлении:

<DataGridTemplateColumn Header=".i." HeaderStyle="{StaticResource CenteredColumnHeaderStyle}" Width="45" IsReadOnly="False">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <ComboBox Height="23" SelectedValuePath="Name" DisplayMemberPath="Name" 
                      SelectedValue="{Binding Value.Lot.TypeImpression, UpdateSourceTrigger=PropertyChanged}" 
                      >
                <ComboBox.Style>
                    <Style TargetType="{x:Type ComboBox}" BasedOn="{StaticResource AnfComboBoxStyle}">
                        <Setter Property="ItemsSource" Value="{Binding DataContext.AvailableTypeImpression, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}"/>
                        <Setter Property="ItemContainerStyle">
                            <Setter.Value>
                                <Style TargetType="ComboBoxItem" BasedOn="{StaticResource {x:Type ComboBoxItem}}">
                                    <Style.Triggers>
                                        <DataTrigger Binding="{Binding IsAvailable}" Value="False">
                                            <Setter Property="Visibility" Value="Collapsed" />
                                        </DataTrigger>
                                    </Style.Triggers>
                                </Style>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </ComboBox.Style>
            </ComboBox>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

И все работает отлично :)

enter image description here

0 голосов
/ 21 февраля 2020

Я не знаю, как сделать отдельные элементы невыбираемыми в поле со списком. Но вы всегда можете отобразить поле со списком без недопустимых букв (т.е. удалить их из AvailableTypeImpression) и вместо этого показать просто TextBlock в своей ячейке на случай, если одна из этих букв будет прочитана из БД.

Измените шаблон ячейки на что-то вроде этого:

<DataGridTemplateColumn.CellTemplate>
    <DataTemplate>
        <Grid>
            <ComboBox Visbility="{Binding IsValueEditable}" Height="23" Style="{StaticResource AnfComboBoxStyle}" ItemsSource="{Binding DataContext.AvailableTypeImpression, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}" SelectedItem="{Binding Value.Lot.TypeImpression, UpdateSourceTrigger=PropertyChanged}" />
            <TextBlock Visbility="{Binding NotIsValueEditable}" Height="23" Text="{Binding Value.Lot.TypeImpression}" />
        </Grid>
    </DataTemplate>
</DataGridTemplateColumn.CellTemplate>

Затем реализуйте свойства IsValueEditable, NotIsValueEditable в вашей модели представления, чтобы отображался только один из элементов управления.

В качестве альтернативы, если вы также хотите иметь возможность изменять существующие записи M, p, P, R, вы можете использовать DataGridTemplateColumn.CellEditingTemplate : заставить CellEditingTemplate показывать ComboBox (без M, p , P, R), тогда как обычный CellTemplate содержит только TextBlock.

<DataGridTemplateColumn.CellTemplate>
    <DataTemplate>
        <TextBlock Height="23" Text="{Binding Value.Lot.TypeImpression}" />
    </DataTemplate>
</DataGridTemplateColumn.CellTemplate>

<DataGridTemplateColumn.CellEditingTemplate>
    <DataTemplate>
        <ComboBox Height="23" Style="{StaticResource AnfComboBoxStyle}" ItemsSource="{Binding DataContext.AvailableTypeImpression, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}" SelectedItem="{Binding Value.Lot.TypeImpression, UpdateSourceTrigger=PropertyChanged}" />
    </DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
...