ComboBox SelectedValue not changing from binding to Dependency Property

非 Y 不嫁゛ 提交于 2019-12-13 04:39:59

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!