我正在尝试制作一个显示复选框的组合框,选中每个复选框将更新组合框的文本以显示已检查的所有内容。由于一些奇怪的原因,它只适用于复选框中的第一项,它完全困扰我为什么。我有一个非常小的虚拟项目来演示它......
public partial class MainWindow : Window
{
public ObservableCollection<DataObject> Collection { get; set; }
#region Private Methods
public MainWindow()
{
InitializeComponent();
Collection = new ObservableCollection<DataObject>();
Collection.Add(new DataObject { Name = "item1" });
Collection.Add(new DataObject { Name = "item2" });
Collection.Add(new DataObject { Name = "item3" });
Collection.Add(new DataObject { Name = "item4" });
Collection.Add(new DataObject { Name = "item5" });
this.DataContext = Collection;
}
#endregion
private void CheckBox_Checked(object sender, RoutedEventArgs e)
{
CheckBox chk = sender as CheckBox;
DataObject data = chk.DataContext as DataObject;
if ((bool)chk.IsChecked)
data.CboItems.Add(data.Name);
else if (data.CboItems.Contains(data.Name))
data.CboItems.Remove(data.Name);
}
}
public class DataObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public string Name { get; set; }
private string cbotext;
public string CBOText {
get
{
return cbotext;
}
set
{
cbotext = value;
FirePropertyChanged("CBOText");
}
}
public ObservableCollection<string> CboItems { get; set; }
private void FirePropertyChanged(string name)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
public DataObject()
{
CboItems = new ObservableCollection<string>();
CboItems.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(CboItems_CollectionChanged);
}
void CboItems_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
string text = string.Empty;
foreach (string item in CboItems)
{
if (text == string.Empty)
text = item;
else
text += ", " + item;
}
CBOText = text;
}
}
和Xaml ......
<ComboBox Text="{Binding CBOText}" Width="150" Height="30" ItemsSource="{Binding}" x:Name="cbo" HorizontalContentAlignment="Stretch" IsEditable="True" Margin="12,12,342,270">
<ComboBox.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding Name}" Checked="CheckBox_Checked" Unchecked="CheckBox_Checked" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
我可以看到事件CBOText字符串设置正确并触发PropertyChanged,但组合框不反映它,除非它是第一项。很奇怪,有什么想法吗?
答案 0 :(得分:1)
您的绑定设置不正确。尝试这样的事情:
public partial class MainWindow : Window, INotifyPropertyChanged
{
public ObservableCollection<DataObject> Collection { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
#region Private Methods
public MainWindow()
{
InitializeComponent();
Collection = new ObservableCollection<DataObject>();
Collection.Add(new DataObject { Name = "item1" });
Collection.Add(new DataObject { Name = "item2" });
Collection.Add(new DataObject { Name = "item3" });
Collection.Add(new DataObject { Name = "item4" });
Collection.Add(new DataObject { Name = "item5" });
this.DataContext = this;
}
#endregion
private void CheckBox_Checked(object sender, RoutedEventArgs e)
{
CheckBox chk = sender as CheckBox;
DataObject data = chk.DataContext as DataObject;
string combinedText = string.Empty;
foreach (var item in this.Collection)
{
if (item.IsChecked.HasValue && item.IsChecked.Value)
{
if (combinedText == string.Empty)
combinedText = item.Name;
else
combinedText += ", " + item.Name;
}
}
CboText = combinedText;
}
private string _cboCombinedText = "" ;
public string CboText
{
get
{
return this._cboCombinedText; }
set
{
this._cboCombinedText = value;
PropertyChanged(this, new PropertyChangedEventArgs("CboText"));
}
}
public class DataObject
{
private bool? _isChecked = false;
public string Name { get; set; }
public bool? IsChecked { get { return _isChecked; } set { _isChecked = value; } }
}
}
和xaml:
<ComboBox Text="{Binding CboText}" Width="150" Height="30" ItemsSource="{Binding Path=Collection}" x:Name="cbo" HorizontalContentAlignment="Stretch" IsEditable="True" Margin="12,12,342,270">
<ComboBox.ItemTemplate >
<DataTemplate >
<CheckBox Content="{Binding Name}" Checked="CheckBox_Checked" Unchecked="CheckBox_Checked" IsChecked="{Binding IsChecked}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>