属性更改时,Combobox项不会更新

时间:2015-05-07 14:58:15

标签: c# wpf xaml mvvm surface

我有一个包含两个项目的ComboBox(买入和卖出)。但是当PropertyChanged(Sell)仍然没有更新comboBox(仍然选择了Buy)。我正在使用带有Windows应用程序的.Net 4.5的VS2013。请帮助我。 这是XMAL代码

<ComboBox HorizontalAlignment="Left"  Grid.Row="5" Grid.Column="0" x:Name="cmbInputAction"   VerticalAlignment="Top" Margin="10,0,0,0" Width="195" ItemsSource="{Binding OrderActions}" DisplayMemberPath="DisplayName" SelectedItem="{Binding CurrentOrderAction, Mode=TwoWay}"/>

这是我的viewmodel

public static readonly DependencyProperty CurrentOrderActionProperty =
        DependencyProperty.Register("CurrentOrderAction", typeof(ComboBoxItem), typeof(OrderScreenViewModel),
                                    new PropertyMetadata(new ComboBoxItem("Buy", 1)));

    public ComboBoxItem CurrentOrderAction
    {
        get { return (ComboBoxItem)GetValue(CurrentOrderActionProperty); }
        set
        {
            if (value != null)
            {
                SetValue(CurrentOrderActionProperty, value); **//Now Value is Sell but still not display sell value in combobox**
                if (PropertyChanged != null)
                    PropertyChanged(this, new PropertyChangedEventArgs("CurrentOrderAction")); **// Fired this event**

            }

        }
    }

我尝试了对XMAL的更改。但仍未修复。

  1. SelectedValue="{Binding CurrentOrderAction, Mode=TwoWay}"
  2. SelectedItem="{Binding Path = CurrentOrderAction, Mode=TwoWay}"
  3. SelectedValue="{Binding path= CurrentOrderAction, Mode=TwoWay}"
  4. SelectedItem="{Binding Path = CurrentOrderAction, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"

2 个答案:

答案 0 :(得分:1)

我不是百分百肯定这是你的问题,但我百分百肯定你做错了。

您正在尝试在DependencyProperty的setter中工作。这将永远不会正常工作,因为绑定器永远不会触及setter。

Binding系统的工作水平远低于您的财产。因此,当用户更新我的DependencyProperty所绑定的值时,您的类中定义的setter代码将不会执行。

如果在绑定更新DependencyProperty时需要执行某些操作,则需要创建回调。这是一个例子

    #region SomeProperty
    /// <summary>
    /// The <see cref="DependencyProperty"/> for <see cref="SomeProperty"/>.
    /// </summary>
    public static readonly DependencyProperty SomePropertyProperty =
        DependencyProperty.Register(
            SomePropertyPropertyName,
            typeof(object),
            typeof(MainWindow),
            new UIPropertyMetadata(null, OnSomePropertyPropertyChanged));

    /// <summary>
    /// Called when the value of <see cref="SomePropertyProperty"/> changes on a given instance of <see cref="MainWindow"/>.
    /// </summary>
    /// <param name="d">The instance on which the property changed.</param>
    /// <param name="e">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
    private static void OnSomePropertyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        (d as MainWindow).OnSomePropertyChanged(e.OldValue as object, e.NewValue as object);
    }

    /// <summary>
    /// Called when <see cref="SomeProperty"/> changes.
    /// </summary>
    /// <param name="oldValue">The old value</param>
    /// <param name="newValue">The new value</param>
    private void OnSomePropertyChanged(object oldValue, object newValue)
    {
        ;
    }

    /// <summary>
    /// The name of the <see cref="SomeProperty"/> <see cref="DependencyProperty"/>.
    /// </summary>
    public const string SomePropertyPropertyName = "SomeProperty";

    /// <summary>
    /// 
    /// </summary>
    public object SomeProperty
    {
        get { return (object)GetValue(SomePropertyProperty); }
        set { SetValue(SomePropertyProperty, value); }
    }
    #endregion  

请注意,回调是在传递给Register方法的元数据对象中配置的。

您的第二个错误是在DependencyProperty的setter中调用PropertyChanged。这由绑定系统处理。您只是第二次调用它(当然,当您在代码中使用该属性时)。

第三个问题是您的媒体资源属于ComboBoxItem。我勒个去。这不是它的工作方式。您应该绑定到模型并让UI处理创建ComboBoxItems。简化您的代码:

// here's your model
public class OrderAction
{
    public string Name {get;set;}
} 

// here's your VM
public class OrderActionViewModel
{

    public ObservableCollection<OrderAction> Actions { get; private set; }
    // INotifyPropertyChanged implementation left off the following
    public OrderAction CurrentAction { get; set; } 
}

这是你的约束力

<ComboBox ItemsSource="{Binding Actions}"
          SelectedItem="{Binding CurrentAction}" />

现在,只要CurrentAction中的 实例 属于Actions中的实例,ComboBox就会显示正确的选定操作。

例如,如果你这样做,

CurrentAction = Actions.Last(); 

将选择组合框中的最后一项。

答案 1 :(得分:0)

  public class ComboBoxItem
    {
    private string displayName;
    private int value;

    public int Value
    {
        get { return this.value; }
        set { this.value = value; }
    }

    public string DisplayName
    {
        get { return displayName; }
        set { displayName = value; }
    }

    public ComboBoxItem()
    {

    }

    public ComboBoxItem(string name, int value)
    {
        this.displayName = name;
        this.value = value;
    }

    **public override bool Equals(object obj)
    {
        return (obj is ComboBoxItem) && (obj as ComboBoxItem).Value.Equals(this.Value);
    }**
}