2010-11-12 242 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); 
       } 
      } 
     } 

    } 
}