2011-11-30 42 views
2

我有一个类ParamObj(其实现INotifyPropertyChanged),其中包含ObservableCollection<Param>类型的属性DefaultValues。我的Param类(它也实现了INotifyPropertyChanged)包含两个属性:NameIsSelected将对象绑定到组合框填充列表,但选择更改未在CSharp中的对象中更新

按钮单击我正在填充StackPanelTextBlockComboBox控件。集合DefaultValues中的每个ParamComboBox中的一个选项,其中Name属性表示该选项的文本,IsSelected是布尔值,表示该选项是否为当前在ComboBox中选择的选项。下面

Param类:下面

public class Param : INotifyPropertyChanged 
{ 
    public enum ParamType 
    { 
     Unknown=-1, 
     Text=0, 
     Option=1, 
     Multi=2 
    } 

    private string pName = string.Empty; 
    private bool pSelected = false; 
    private ParamType pType = ParamType.Unknown; 

    public string Name { get { return pName; } set { pName = value; OnPropertyChanged("Name"); } } 
    public bool IsSelected { get { return pSelected; } set { pSelected = value; OnPropertyChanged("IsSelected"); } } 
    public ParamType Type { get { return pType; } } 

    public Param(string name, bool selected) 
    { 
     this.pName = name; 
     this.pSelected = selected; 
     this.pType = ParamType.Option; 
    } 

    //INotifyPropertyChanged base 
    public event PropertyChangedEventHandler PropertyChanged; 

    protected void OnPropertyChanged(string name) 
    { 
     PropertyChangedEventHandler handler = PropertyChanged; 
     if (handler != null) 
      handler(this, new PropertyChangedEventArgs(name)); 
    } 
} 

ParamObj类:下面

public class ParamObj : INotifyPropertyChanged 
{ 
    //ui type mapping 
    public enum UITypeEnum 
    { 
     Textbox = 0, 
     ComboBox = 1, 
     CheckableComboBox = 2 
    } 

    private string name = string.Empty; 
    private UITypeEnum uiType = UITypeEnum.Textbox; 
    private ObservableCollection<Param> defaultVals = new ObservableCollection<Param>(); 
    private string propDescription = string.Empty; 

    public string Name { get { return name; } set { name = value; OnPropertyChanged("Name"); } } 
    public UITypeEnum UIType { get { return uiType; } set { uiType = value; OnPropertyChanged("UIType"); } } 
    public ObservableCollection<Param> DefaultValues { get { return defaultVals; } } 
    public string Desc { get { return propDescription; } set { propDescription = value; } } 

    //Initialization 
    public ParamObj() 
    { 

    } 

    public void ClearDefaultValues() 
    { 
     this.defaultVals.Clear(); 
     OnPropertyChanged("DefaultValues"); 
    } 

    public void AddDefaultValue(Param objAdded) 
    { 
     this.defaultVals.Add(objAdded); 
    } 

    public void AddDefaultValueRange(Param[] objsToAdd) 
    { 
     foreach (Param o in objsToAdd) 
     { 
      this.defaultVals.Add(o); 
     } 
    } 

    //INotifyPropertyChanged base 
    public event PropertyChangedEventHandler PropertyChanged; 

    protected void OnPropertyChanged(string name) 
    { 
     PropertyChangedEventHandler handler = PropertyChanged; 
     if (handler != null) 
      handler(this, new PropertyChangedEventArgs(name)); 
    } 
} 

代码是所谓的按钮单击事件。 po代表ParamObj实例。

case ParamObj.UITypeEnum.ComboBox: 
    cb = new ComboBox(); 
    cb.Height = 26; 
    cb.Width = 210; 
    cb.Margin = new Thickness(2); 
    cb.VerticalContentAlignment = System.Windows.VerticalAlignment.Center; 
    cb.DataContext = po.DefaultValues; 
    //binding 
    cb.ItemsSource = po.DefaultValues; 
    cb.DisplayMemberPath = "Name";       
    cb.SelectedValuePath = "IsSelected"; 
    cb.SelectedValue = true; 

    cb.SelectionChanged += ParamComboBox_SelectionChanged; 
    break; 

问题出在这里。 ComboBox项目已成功填充,并且已选中具有IsSelectedtrue的选项(Param对象)。我认为会发生的是,当我更改ComboBox中的选定选项时,Param对象的IsSelected属性的值(布尔值)将从false切换为true。这没有发生。所以我将cb.SelectionChanged += ParamComboBox_SelectionChanged事件添加到ComboBox

private void ParamComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) 
    { 
     if (!(sender is ComboBox)) return; 

     ComboBox cb = sender as ComboBox; 
     Param cp = (Param)cb.SelectedItem; 
     if (cp.IsSelected == false) 
     { 
      foreach (Param p in cb.ItemsSource) 
      { 
       p.IsSelected = false; 
      } 
      cp.IsSelected = true; 
     } 
    } 

经过调试我看到IsSelected属性正确更新,但不更新用新值我po对象的值。

任何建议,非常感谢。我已经尝试过我的最坏的想法,但我被卡住了。

布赖恩

回答

0

这是似乎是很简单的一个问题,但似乎没有对ComboBoxItem IsSelected结合给定的属性没有简单的或直接的方式。我想到的一种可能的解决方案可能是:

首先,将ComboBoxItem类型的样式添加到您的ComboBox并向该样式添加触发器。这触发条件会当你选择了一个ComboBoxItem并调用辅助类在步骤2中

 <ComboBox Name="TestCombo" ItemsSource="{Binding Path=DataSource.DefaultValues}" DisplayMemberPath="Name" SelectedValuePath="IsSelected" SelectionChanged="Test_SelectionChanged"> 
       <ComboBox.Resources>      
        <Style TargetType="{x:Type ComboBoxItem}"> 
         <Style.Triggers> 
          <Trigger Property="IsSelected" Value="True"> 
           <Setter Property="StackOverflow:IsSelectedBehavior.IsSelected" Value="True"></Setter> 
          </Trigger> 
          <Trigger Property="IsSelected" Value="False"> 
           <Setter Property="StackOverflow:IsSelectedBehavior.IsSelected" Value="False"></Setter> 
          </Trigger> 
         </Style.Triggers> 
        </Style> 
       </ComboBox.Resources> 
      </ComboBox> 

如果您希望以编程方式做同样的事情,那么你去:

 Style style = new Style(); 
     Trigger t = new Trigger(); 
     style.TargetType = typeof(ComboBoxItem); 
     t.Property = ListBoxItem.IsSelectedProperty; 
     t.Value = true; 
     Setter setter = new Setter(IsSelectedBehavior.IsSelectedProperty, true); 
     t.Setters.Add(setter); 
     style.Triggers.Add(t); 
     cb.Resources.Add(typeof(ComboBoxItem), style); 

然后,创建一个IsSelectedBehaviorClass来处理您的IsSelected行为。此静态类将接收当前选定的ComboBoxItem并相应地设置Param.IsSelected属性。事情是这样的:

public static class IsSelectedBehavior 
    { 
     public static readonly DependencyProperty IsSelectedProperty = DependencyProperty.RegisterAttached(
      "IsSelected", typeof (bool), typeof (IsSelectedBehavior), new UIPropertyMetadata(false, OnIsSelected)); 

     public static bool GetIsSelected(DependencyObject d) 
     { 
      return (bool) d.GetValue(IsSelectedProperty); 
     } 

     public static void SetIsSelected(DependencyObject d, bool value) 
     { 
      d.SetValue(IsSelectedProperty, value); 
     } 

     public static void OnIsSelected(DependencyObject d, DependencyPropertyChangedEventArgs e) 
     { 
      //Get current ComboBoxItem 
      ComboBoxItem test = d as ComboBoxItem; 
      //Get the current Param from the ComboBoxItem.Content 
      Param p = test.Content as Param; 
      //Set the Param.IsSelected property 
      p.IsSelected = (bool) e.NewValue; 
     } 
    } 

最后,你可以测试你的的SelectionChanged事件处理

private void ParamComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) 
     { 
      Param selected = cb.SelectedItem as Param; 
      if (selected != null) 
      { 
       Debug.WriteLine("Selection Changed: Selected " + selected.Name); 
      } 
      StringBuilder str = new StringBuilder(); 
      foreach (var obj in cb.Items) 
      { 
       Param p = obj as Param; 
       str.Append("Name:" + p.Name + " IsSelected:" + p.IsSelected + Environment.NewLine); 
       Debug.WriteLine(str); 
      } 
      MessageBox.Show(str.ToString()); 
     } 
解决方案
相关问题