当 属性 更改时,组合框项目不会更新

Combobox item does not updates when the property changes

我有一个包含两个项目(买入和卖出)的组合框。但是当 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}"/>

这是我的视图模型

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}"

我不是 100% 确定这是你的问题,但我 100% 确定你做错了。

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

绑定系统的工作级别比您的 属性 低得多。因此,当用户更新我的 DependencyProperty 绑定到的值时,class 中定义的 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(); 

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

  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);
    }**
}