WPF - 复选框的组合框 - 选择绑定?

时间:2010-11-12 17:58:22

标签: wpf templates binding checkbox

我已经实现了一个CheckBoxes的ComboBox,它在GUI中看起来很不错,但我在使用它时遇到了麻烦。

我遇到的主要问题是弄清楚实际检查了哪些方框。在运行时,ComboBox.SelectedItem正常工作,但如果我遍历所有项目,它们总是返回IsSelected == false。

有什么想法吗?

这是我的xaml:

<ComboBox Name="cboParam3" Grid.Row="0" Grid.Column="5" SelectedValuePath="Key" KeyDown="headerBar_KeyDown">
   <ComboBox.ItemTemplate>
      <DataTemplate>
         <StackPanel Orientation="Horizontal">
            <CheckBox IsChecked="{Binding Path=IsSelected}" VerticalAlignment="Center" Margin="0,0,4,0" />
            <TextBlock Text="{Binding Value}" VerticalAlignment="Center"/>
         </StackPanel>
      </DataTemplate>
   </ComboBox.ItemTemplate>
</ComboBox>

这是我最初填充组合框的代码:

Dictionary<int, string> codes = CodeCache.CodeLookup<DACaseCategoryCode>();
List<MultipleComboItem> items = new List<MultipleComboItem>();

codes.ToList().ForEach(t =>
{
   MultipleComboItem item = new MultipleComboItem();

   item.Key = t.Key;
   item.Value = t.Value;
   item.IsSelected = false;

   items.Add(item);
});

this.lblParam3.Content = "Case Category:";
this.cboParam3.ItemsSource = items;

我需要在混音中添加其他内容才能使其正常工作吗?

谢谢,
桑尼

PS MultipleComboItem只是一个具有三个属性的简单结构。没有什么奇特的事发生在那里。

4 个答案:

答案 0 :(得分:1)

<ComboBox Name="identifiercombo" Text="{Binding SelectedIdentifier, UpdateSourceTrigger=PropertyChanged}"  ItemsSource="{Binding IdentifierCollection}"  SelectedIndex="0" IsEditable="True" Grid.Row="3" Grid.Column="1" HorizontalAlignment="Stretch" Margin="10,5">
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <CheckBox Click="CheckBox_Click" Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content,UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Center"/>                            
            </StackPanel>
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

答案 1 :(得分:0)

编辑:

我写了一个快速测试应用程序,使用以下内容绑定似乎工作正常(但是,选中复选框不会设置组合框的SelectedItem属性):

<Window x:Class="TestApp11.MainWindow" 
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
  xmlns:l="clr-namespace:TestApp11"
  Title="Window1" >
    <Window.Resources>
    </Window.Resources>
    <Grid Background="Black">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <ComboBox Name="cboParam3" Grid.Row="0" Grid.Column="0">
            <ComboBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <CheckBox IsChecked="{Binding Path=Select}" VerticalAlignment="Center" Margin="0,0,4,0" />
                        <TextBlock Text="{Binding Name}" VerticalAlignment="Center"/>
                    </StackPanel>
                </DataTemplate>
            </ComboBox.ItemTemplate>
            </ComboBox>
        <Button Grid.Row="1" Content="Click Me For Break Point" Click="Button_Click"></Button>
    </Grid>
</Window>


using System.Collections.ObjectModel;
using System.Windows;

namespace TestApp11
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    public ObservableCollection<MCI> MCIList { get; set; }
    public MainWindow()
    {
        InitializeComponent();
        this.MCIList = new ObservableCollection<MCI>();
        this.cboParam3.ItemsSource = this.MCIList;

        this.MCIList.Add(new MCI());
        this.MCIList.Add(new MCI());
        this.MCIList.Add(new MCI());
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {

    }

}

public class MCI
{
    public bool Select { get; set; }
    public string Name { get; set; }
    public MCI()
    {
        this.Name = "Bob";
        this.Select = false;
    }
}
}

你做的事与我上面有什么不同吗?

答案 2 :(得分:0)

  

ComboBox.SelectedItem正常工作

好的,您可以选择MultipleComboItem。

  

如果我遍历所有项目,它们总是返回IsSelected == false。

那是因为你绑定了IsChecked =“{Binding Path = IsSelected}”,如果你勾选打开的组合框列表中的复选框并再次遍历这些项目,你可以找到IsSelected == true的项目。

因此,如果您不选中复选框,则不会找到IsSelected == true。

您必须感觉到组合框的已选择项目与显示该项目的已选中复选框之间存在差异。

答案 3 :(得分:0)

我需要创建一个自定义的复选框组合框,以显示供用户选择的日历月份列表。此应用程序将允许用户选择月份,每当选择或取消选择月份时,都会更新列表框。我遍历可观察集合,这是组合框的项目源,以确定已检查的月份。我可以使用LINQ查询集合,而不是手动迭代可观察集合,但这是另一天。如果你想测试一下,只需创建一个名为CustomComboBox的新wpf应用程序(在C#中),然后将xaml和c#复制并粘贴到你的应用程序中:

<Window x:Class="CustomComboBox.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>

    </Window.Resources>
    <Grid>      
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="30" />
                <RowDefinition Height="30"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition />            
            </Grid.ColumnDefinitions>
            <Label Grid.Column="0" Grid.Row="0" Content="Select the months:" />
            <Label Grid.Column="1" Grid.Row="1" Content="Months selected:" />
            <ComboBox x:Name="ComboBoxMonths" Grid.Column="0" Grid.Row="1">
                <ComboBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <CheckBox IsChecked="{Binding Path=monthSelected}" VerticalAlignment="Center" Margin="0,0,4,0" Checked="CheckBox_Checked" Unchecked="CheckBox_Unchecked" />
                            <TextBlock Text="{Binding monthName}" VerticalAlignment="Center"/>
                        </StackPanel>
                    </DataTemplate>
                </ComboBox.ItemTemplate>
            </ComboBox>
            <ListBox x:Name="ListBoxMonthsChecked" Grid.Column="1" Grid.Row="2">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding monthName}" VerticalAlignment="Center"/>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
        </Grid>       
    </Grid>

</Window>

c#代码:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace CustomComboBox
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public static ObservableCollection<Month> monthList = new ObservableCollection<Month>();
        public static ObservableCollection<Month> monthsChecked = new ObservableCollection<Month>();

        public MainWindow()
        {
            InitializeComponent();

            this.ComboBoxMonths.ItemsSource = monthList;
            this.ListBoxMonthsChecked.ItemsSource = monthsChecked;

            //add Months to the ComboBoxMonths
            monthList.Add(new Month() { monthSelected = false, monthName = "January", monthNumber = 01 });
            monthList.Add(new Month() { monthSelected = false, monthName = "February", monthNumber = 02 });
            monthList.Add(new Month() { monthSelected = false, monthName = "March", monthNumber = 03 });            
            monthList.Add(new Month() { monthSelected = false, monthName = "April", monthNumber = 04 });
            monthList.Add(new Month() { monthSelected = false, monthName = "May", monthNumber = 05 });
            monthList.Add(new Month() { monthSelected = false, monthName = "June", monthNumber = 06 });
            monthList.Add(new Month() { monthSelected = false, monthName = "July", monthNumber = 07 });
            monthList.Add(new Month() { monthSelected = false, monthName = "August", monthNumber = 08 });
            monthList.Add(new Month() { monthSelected = false, monthName = "September", monthNumber = 09 });
            monthList.Add(new Month() { monthSelected = false, monthName = "October", monthNumber = 10 });
            monthList.Add(new Month() { monthSelected = false, monthName = "November", monthNumber = 11 });
            monthList.Add(new Month() { monthSelected = false, monthName = "December", monthNumber = 12 });
        }

        public class Month
        {
            public string monthName { get; set; } 
            public int monthNumber { get; set; } 

            private bool _monthSelected;
            public bool monthSelected //the checkbox is bound to this
            {
                get
                {
                    return _monthSelected;
                }
                set
                {
                    if (value != this._monthSelected)
                    {
                        _monthSelected = value;                        
                    }
                }
            }

        }

        private void CheckBox_Checked(object sender, RoutedEventArgs e)
        {
            monthsChecked.Clear();
            foreach (Month m in monthList)
            {
                if (m.monthSelected == true)
                {                    
                    monthsChecked.Add(m);
                }
            }            
        }

        private void CheckBox_UnChecked(object sender, RoutedEventArgs e)
        {
            monthsChecked.Clear();
            foreach (Month m in monthList)
            {
                if (m.monthSelected == true)
                {
                    monthsChecked.Add(m);
                }
            }
        }

    }
}
相关问题