Combobox与复选框

时间:2012-03-03 16:40:07

标签: c# wpf

我正在尝试制作一个显示复选框的组合框,选中每个复选框将更新组合框的文本以显示已检查的所有内容。由于一些奇怪的原因,它只适用于复选框中的第一项,它完全困扰我为什么。我有一个非常小的虚拟项目来演示它......

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,但组合框不反映它,除非它是第一项。很奇怪,有什么想法吗?

1 个答案:

答案 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>