2

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

我已经做到了。但是,由于我使用的是 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 上的事件,除了复选框的屏幕区域等)

4

1 回答 1

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/>

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

于 2012-04-16T17:19:19.603 回答