问题
I have a Custom Control:
I don't want to get into specifics so for simplicity's sake i have 3 Dependency Properties :
MyCustomControl (CS) :
public class MyCustomControl : Control
{
DP Value1
DP InternalValue
DP SelectedValue
OnValue1Changed()
{
InternalValue = CalculateBasedOn1();
}
static bool _isSetInternally;
OnInternalValueChanged()
{
if(Condition())
{
_isSetInternally = true;
SelectedValue = e.NewValue;
}
else
{
Value1 = FixValue1();
}
}
OnSelectedValueChanged()
{
if(_isSetInternally)
{
_isSetInternally = false;
return;
}
Value1 = ExtractValue1FromInput(e.NewValue);
}
public List<string> Values
{
get{ return new List<string>() { "1","2",......,"200"};}
}
}
My ControlTemplate (Again Simplified) :
<ControlTemplate>
<ComboBox x:Name="cb"
ItemsSource="{Binding RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay, Path=Values}"
SelectedItem={Binding RelativeSource={RelativeSource TemplatedParent}, Path=Value1, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}
</ControlTemplate>
The Problem : cb is showing the last value chosen , even after it was fixed as explained below .
Flow :
1) Input :
1.1) SelectedValue is bound to a property in my DataContext , it receives a value.
1.2) OnSelectedValueChanged() sets Value1.
1.3) Value1 Sets "cb" SelectedItem via binding.
1.4) OnValue1Changed sets InternalValue.
1.5) OnInternalValueChanged() flags _isSetInternally = true and Updates SelectedValue.
1.6) OnSelectedValueChanged() zeros _isSetInternally = false and stops flow (return).
2) Output :
2.1) cb's SelectedItem is changed.
2.2) Value1 is set via Binding.
2.3) OnValue1Changed() sets InternalValue.
2.4) If Condition is met propagate Output.
2.4.1) go to (1.4)
2.4.2) THE PROBLEM , Condition was not met, Set Value1 again with a valid value.
2.5) go to (1.4)
The Problem in 2.4.2 is that The ComboBox is still showing the non - valid value chosen in (2.1)
Observing with snoop i can see that the SelectedItem is correct and have been changed , but the SelectedValue and SelectedIndex are still the one's chosen before the Fix.
*Further more iv'e attempted to Coerce Value1 on a Coercion Callback , it had the same effect.
Any idea's why the ComboBox doesn't update it's Value via Binding in this scenario ?
回答1:
I don't know if I did understand well the problem, but what you should have would be a Binding to the SelectedItem in Combobox.
When that value changes, you should raise a PropertyChanged event with the INotifyPropertyChanged.
In your combo, you then have the properties DisplayMemberPath and SelectedValuePath.
Can you work with it?
Regards,
回答2:
O'k so the problem as it seems was some synchronization issue in the ComboBox according to this article :
http://ikriv.com/dev/wpf/ConfusedComboBox/index.shtml
special thanks to Uriel Jacobson
it is recommended to make the update on the ComboBox asynchronously using Dispatcher.BeginInvoke(...)
OnInternalValueChanged()
{
if(Condition())
{
_isSetInternally = true;
SelectedValue = e.NewValue;
}
else
{
Application.Current.Dispatcher.BeginInvoke(new System.Action(() =>
{
Value1 = FixValue1();
}));
}
}
Edit : 19.7.2014
Though this did patch and fix this issue , i later re-wrote the entire control in a much simpler fashion , one of the things i did was remove the ValidationRule i placed on the Binding to the Combobox's SelectedItem.
When doing so , the Binding between my DependencyProperty and the Combox's SelectedItem updated normally. FYI , I removed the use of WPF Validation system all together in my experience they just don't work well (I of course usually use other words to describe WPF Validations , but not here :) ).
回答3:
I didn't quite follow the process here, but I think Value1
is never set if your code follows the happy path. It looks like after Value1
is set with the "non-corrected" value, you set InternalValue
, and then set SelectedValue
like this:
if(Condition())
{
_isSetInternally = true;
SelectedValue = e.NewValue;
}
And after that OnSelectedValueChanged
just resets the flag and exists:
if(_isSetInternally)
{
_isSetInternally = false;
return;
}
You never seem to correct Value1
.
But I may be way off here.
来源:https://stackoverflow.com/questions/22300281/combobox-selectedvalue-not-changing-from-binding-to-dependency-property