2010-11-12 210 views
1

我已经实现了一个复选框组合框,在GUI中看起来很不错,但是我在功能上使用它时遇到了麻烦。WPF - 复选框组合框 - 绑定IsSelected?

我遇到的主要问题是搞清楚哪些盒子实际上被检查。在运行时,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仅仅是一个简单的结构具有三个属性。那里没有什么奇特的事情发生

回答

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; 
    } 
} 
} 

你在做什么与我上面有很大不同吗?

+0

无当我更改属性的名称时有所不同。 – 2010-11-12 19:25:34

+0

我编辑了我的解决方案以显示正确绑定的快速示例项目。这听起来像你有什么应该正确绑定属性......但我不认为点击复选框应该设置combobox.selected项属性。在我上面提供的例子中。点击一个项目的复选框会产生与单击文本“Bob”不同的结果。 (后者设置了cboParam3.selecteditem,只需点击一个复选框就会更新MCI对象的Select属性,但不会设置cboParam3.SelectedItem属性,希望这会有所帮助! – Scott 2010-11-12 20:34:21

+0

鉴于我可以检查多个复选框,我得到了多重选择的项目?ComboBox的ItemSource包含我所有的MCI,但是当我检查其中一个复选框时,Selected属性似乎不会被设置为true或false ... – 2010-11-12 20:49:41

0

ComboBox.SelectedItem正常工作

好吧,你可以得到选择MultipleComboItem。

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

这是因为已经绑定器isChecked =“{绑定路径= IsSelected}”,如果您在打开框列表复选框,并通过项目迭代再​​次,你可以找到项目与IsSelected ==真。

所以,如果你没有选择复选框,你不会发现IsSelected == true。

您必须感觉区别选中项目的组合框和选中复选框,呈现该项目。

+0

是的。我不关心组合框的SelectedItem。我需要找到哪些复选框被选中。我试图说,然后当我检查SelectedItem(这是MultipleComItems之一)它正确显示Selected属性。当我遍历所有的ComboBox.Items虽然,似乎没有选择。 – 2010-11-12 21:13:26

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

我需要创建复选框的自定义组合框来显示用户选择的日历月份列表。这个应用程序将允许用户选择月份,每当选择或取消选择一个月时,都会更新列表框。我遍历可观察的集合,它是组合框的项目源,以确定哪些月份已被检查。我可以使用LINQ查询集合,而不是通过手动迭代可观察集合,但那是另一天。如果你想测试这一点,只需创建一个名为CustomComboBox(在C#)一个新的WPF应用程序,并复制和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); 
       } 
      } 
     } 

    } 
}