web-dev-qa-db-ja.com

WPFで無効にされたコンボボックス項目の選択を禁止/ブロック

ComboBoxのいくつかのアイテムを無効にし、無効化されたアイテムの選択を許可またはブロックしたいアプリケーションを書いています。メインウィンドウのComboBoxには、ComboBox Item init(実行時にデータテンプレートセレクターによって決定される)として別のComboBoxがあることに注意してください。

以下のコードを使用して、ComboBox内のComboBoxを無効にすることができますが、無効にされたComboBoxアイテムをユーザーが選択するのを妨げることはありません。無効化されたアイテムの選択を禁止/ブロックする際の助けがあれば役に立ちます。

以下はコードスニペットです

メインウィンドウのコンボボックス:

<Grid>
    <ComboBox HorizontalAlignment="Left" VerticalAlignment="Top" 
              Width="120" Margin="87.2,44.8,0,0" 
              ItemsSource="{Binding Cars}" 
              ItemsPanel="{DynamicResource ItemsPanelTemplateHorizontal}"
              ItemTemplateSelector="{StaticResource QualityComboBoxTemplateSelector}"
              SelectedItem="{Binding SelectedItm}"/>
</Grid>

データテンプレートセレクタ:

public class QualityComboBoxTemplateSelector : DataTemplateSelector
{
    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        var element = container as FrameworkElement;

        var dataTemplate = element.FindResource(((item is string) && item.Equals("Ferrari")) ?
                                                       "DataTemplateTopLevelCombobox2" : "DataTemplateTopLevelCombobox1") as DataTemplate;

        return dataTemplate;
    }
}

上記のComboBoxのデータテンプレート:

<DataTemplate x:Key="DataTemplateTopLevelCombobox1">
    <Border BorderBrush="Black" BorderThickness="1" >
        <TextBlock HorizontalAlignment="Left" 
                   TextWrapping="Wrap" Text="{Binding}"     
                   VerticalAlignment="Top"/>
    </Border>
</DataTemplate>

<DataTemplate x:Key="DataTemplateTopLevelCombobox2">
    <Border Width="100">
        <ComboBox Text="Custom" Height="21.96"
        ItemsSource="{Binding DataContext.Models, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"
        IsEnabled="{Binding DataContext.EnableCombo, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" />
    </Border>
</DataTemplate>
19
vmore

これを行うには、IsEnabledComboBoxItemプロパティをfalseに設定します。

したがって、ComboBoxのItemSource(つまり、Cars)の各項目は、有効にするか無効にするかを指定するプロパティ(IsSelectableなど)を持つオブジェクトにすることができます。アイテムを選択不可にするスタイルを指定します。このようなもの -

<Style TargetType="ComboBoxItem"> 
   <Setter Property="IsEnabled" Value="{Binding IsSelectable}"/> 
</Style> 

更新:

<Grid>
    <ComboBox
        Width="120"
        Margin="87.2,44.8,0,0"
        HorizontalAlignment="Left"
        VerticalAlignment="Top"
        ItemTemplateSelector="{StaticResource QualityComboBoxTemplateSelector}"
        ItemsPanel="{DynamicResource ItemsPanelTemplateHorizontal}"
        ItemsSource="{Binding Cars}"
        SelectedItem="{Binding SelectedItm}">
        <ComboBox.ItemContainerStyle>
            <Style TargetType="ComboBoxItem">
                <Setter
                    Property="IsEnabled"
                    Value="{Binding IsSelectable}" />
            </Style>
        </ComboBox.ItemContainerStyle>
    </ComboBox>
</Grid>
30
akjoshi

@JordyBoomによって指摘された問題を解決するため。

ItemsContainerGeneratorは、ドロップダウンが少なくとも1回開かれるまでアイテムを生成しません。

したがって、ドロップダウンを開いて、ウィンドウの読み込まれたイベントハンドラーでもう一度閉じると、すべてのマウスとキーボードの選択で正常に動作するはずです。

    public MainWindow()
    {
        InitializeComponent();
        this.Loaded += new RoutedEventHandler(onLoaded);
    }

    private void onLoaded(object sender, RoutedEventArgs e)
    {
         cmbx.IsDropDownOpen = true;
         cmbx.IsDropDownOpen = false;
    }

ソース: WPF:コンボボックスの項目を無効にする–キーボードを使用してアクセスした場合も

5
Flot2011