Reputation: 1185
I have a ComboBox with two items (Buy and Sell). but when PropertyChanged (Sell) still not update comboBox(still selected Buy). I 'm working with VS2013 with .Net 4.5 with Windows app .Please help me. This is XMAL code
<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}"/>
This is my 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**
}
}
}
I tried bellow changes for XMAL. but still not fixed.
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}"
Upvotes: 0
Views: 163
Reputation: 1185
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);
}**
}
Upvotes: 0
Reputation:
I'm not 100% sure this is your issue, but I'm 100% sure you're doing things wrong.
You're attempting to do work in the setter for your DependencyProperty. This will never work correctly, as the setter is never touched by bindings.
The Binding system works at a much lower level than your property. So when the user updates a value my DependencyProperty is bound to, the setter code defined in your class won't execute.
If you need to do something when a binding updates your DependencyProperty, you need to create a callback. Here's an example
#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
Notice the callback is configured in the metadata object passed to the Register
method.
Your second error is calling PropertyChanged
in the setter of your DependencyProperty. This is handled by the binding system. You're just calling it a second time (when you use the property from within your code, of course).
A third issue is that your property is of type ComboBoxItem
. What the hell. That's not how it works whatsoever. You should be binding to models and let the UI handle creating ComboBoxItems. Simplify your code to this:
// 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; }
}
And here's your binding
<ComboBox ItemsSource="{Binding Actions}"
SelectedItem="{Binding CurrentAction}" />
Now, as long as the instance within CurrentAction
is among the instances within Actions
, the ComboBox will show the correct selected action.
For example, if you did this,
CurrentAction = Actions.Last();
The last item in the combo box will be selected.
Upvotes: 1