当 属性 更改时,组合框项目不会更新
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 进行以下更改。但仍未修复。
SelectedValue="{Binding CurrentOrderAction, Mode=TwoWay}"
SelectedItem="{Binding Path = CurrentOrderAction, Mode=TwoWay}"
SelectedValue="{Binding path= CurrentOrderAction, Mode=TwoWay}"
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);
}**
}
我有一个包含两个项目(买入和卖出)的组合框。但是当 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 进行以下更改。但仍未修复。
SelectedValue="{Binding CurrentOrderAction, Mode=TwoWay}"
SelectedItem="{Binding Path = CurrentOrderAction, Mode=TwoWay}"
SelectedValue="{Binding path= CurrentOrderAction, Mode=TwoWay}"
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);
}**
}