【问题标题】:How to disable the ListItems without disabling the CheckBoxes embedded on them?如何禁用 ListItems 而不禁用嵌入其中的 CheckBox?
【发布时间】:2012-04-27 22:32:00
【问题描述】:

我正在开发一个 ComboBox,它的项目必须有一个 CheckBox。我已经实现了一项功能来参与这些复选框的更改。该功能的一部分从 CheckBoxes 建立 ComboBox 的内容(即,当我选择“pear”、“apple”和“blueberry”时,组合必须检查这些项目,并且它的内容也有 成为'梨;苹果;蓝莓')。

我已经做到了。但是,由于我使用的是 ComboBox,因此每当我单击其复选框外的项目时都会选择项目,因此内容会被项目的文本覆盖。这个 xaml 显示了它是如何编写的:

<ComboBox   IsEditable="True" DataContext="{Binding}" 
        IsTextSearchEnabled="False" IsReadOnly="True">
<ComboBox.ItemTemplate>
    <DataTemplate >
        <StackPanel Orientation="Horizontal">
            <CheckBox IsChecked="{Binding   Path=EstaSeleccionado, 
                                            Mode = TwoWay, 
                                            UpdateSourceTrigger=PropertyChanged}"/>
            <TextBlock Text="{Binding Path=Item.Value}"/>
        </StackPanel>
    </DataTemplate>
</ComboBox.ItemTemplate>

如何在不禁用复选框的情况下禁用列表项?

更新 在您的回答中尝试跳过事件。我知道这可以或多或少地干净和容易地完成;但出于可维护性的考虑,我更喜欢基于 property-xaml 的解决方案(即禁用 ListBoxItem 上的事件,除了复选框的屏幕区域等)

【问题讨论】:

  • 不是 100% 确定,但您可以在您的组合框上挂接到 SelectionChanged 并将处理设置为 true 吗?
  • 我尽量不使用任何事件。实际上,CheckBox 绑定到一个实现 INotifyPropertyChanged 的​​特殊类,因此被选中的项目负责自己的选择而无需中继。但如果我没有得到任何有用的响应或我自己发现它,我将使用事件。

标签: wpf xaml checkbox combobox listitem


【解决方案1】:

Checkbox 控件在 Checkbox 右侧有一个内容区域,用于添加文本、图形等。不要将文本设置在单独的文本块中,而是使用 CheckBox 的 Conent 标记。

<ComboBox.ItemTemplate>
    <DataTemplate>
        <CheckBox IsChecked="{Binding Path=EstaSeleccionado, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
            <TextBlock Text={Binding Path=Item.Value}/>
        </CheckBox>
    </DataTemplate>
</ComboBox.ItemTemplate>

注意:Content标签不需要显式设置,假设打开和关闭Checkbox标签之间的控件是Content。

更新:

对不起,我误解了你的问题。您看到的问题是组合框默认行为在 SelectionChanged 上是将 SelectedText 设置为新的 SelectedItem。要更改此行为,您有两种选择:

  1. 覆盖后面代码中的 SelectionChanged 事件处理程序并以编程方式设置 SelectedText
  2. 将 SelectedText 绑定到 ViewModel 中的属性。当绑定尝试更改值时,让您的属性检查组合框绑定的来源并从选中的项目中构建您的 SelectedText 值。

我推荐选项 #2,如下所示:

代码:

public class CheckItem // This probably should implement INotifyPropertyChanged
{
     public string Name { get; set; }
     public bool IsChecked { get; set; }
}


public class ViewModel : INotifyPropertyChanged
{
    public ObservableCollection<CheckItem> ComboItems { get; set; }

    public string SelectedText 
    {
         get { return selectedText; }
         set { 
             StringBuilder sb = new StringBuilder();
             foreach (var item in ComboItems)
                 if (item.IsChecked)
                     sb.Append(String.Format("{0}; ", item.Name));
             selectedText = sb.ToString();
             // raise property changed here...
         }
    }
}

XAML:

 <ComboBox ItemsSource="{Binding Path=myViewModel.ComboBoxItems}">
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <CheckBox IsChecked="{Binding Path=IsChecked, Mode=TwoWay>
                <TextBlock Text={Binding Path=Name}/>
            </CheckBox>
        </DataTemplate>
    </ComboBox.ItemTemplate>
 <Combobox/>

抱歉,我手边没有编译器,所以其中一些可能无法编译。

【讨论】:

  • 我写了你的sn-p。 ComboBox 继续对文本的单击与对 Checkbox 的单击完全分开。
  • @JuanPabloContreras 我已更新我的答案以更好地回答您的问题。
  • 在我当前的实现上写这个太晚了。我根本没有使用视图模型。到目前为止,我们所做的就是直接修改属性或使用方法有序地修改它们
  • @JuanPabloContreras 那么我建议覆盖 SelectionChanged 处理程序
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-17
  • 2018-06-15
  • 1970-01-01
相关资源
最近更新 更多