当ViewModel中的值发生更改时,PropertyChangedCallback在回调期间不会被触发

时间:2016-09-17 12:18:06

标签: xaml mvvm data-binding dependency-properties caliburn.micro

我有一个使用SearchBox用户控件的视图,SearchBox有两个单选按钮来选择搜索模式 - 即时和延迟。我已将搜索模式绑定到SearchMode属性,并且还为搜索模式创建了自定义依赖项属性。

查看

<controls:SearchBox Grid.Row="0"
              HorizontalAlignment="Right"
              Margin="2" Width="200"                           
              SearchMode="{Binding DataContext.SearchMode, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged }" />

ViewModel.cs

private Mode mSearchMode;
            public Mode SearchMode
            {
                get
                {
                    return mSearchMode;
                }
                set
                {
                    mSearchMode = value;
                    NotifyOfPropertyChange();
                }
            }

      // Called when application is restarted.
      private void ActivateLastSelectedSearchMode(Mode lastselectedMode)
            {    
               // Sets the last selected mode to the search mode      
                SearchMode =  lastselectedMode;
            }

         public enum Mode
            {
                Instant,
                Delayed,
            }

SearchBox.xaml

<UserControl x:Class = "abc.SearchBox"
                 DataContext="{Binding RelativeSource={RelativeSource Self}}" >

   <UserControl.Resources>
            <converters:EnumToBooleanConverter x:Key="EnumToBooleanConverter" />
    </UserControl.Resources>

    <StackPanel Orientation="Vertical">
     <RadioButton Content="{lex:Loc SearchBox:SearchModelInstatOption}"
                 IsChecked="{Binding Path=SearchMode, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter={x:Static local:Mode.Instant}}" />
     <RadioButton Content="{lex:Loc SearchBox:SearchModeDelayedOption}"
                 IsChecked="{Binding Path=SearchMode, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter={x:Static local:Mode.Delayed}}" />
    </StackPanel>
    </UserControl>

SearchBox.xaml.cs

public partial class SearchBox : UserControl
    {
      public static DependencyProperty SearchModeProperty =
                    DependencyProperty.Register(
                        "SearchMode",
                        typeof(Mode),
                        typeof(SearchBox),
                        new FrameworkPropertyMetadata(default(Mode), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnIsSearchModeChanged));

    static void OnIsSearchModeChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
            {            
                var searchBox = obj as SearchBox;
                searchBox.SearchMode = (Mode)e.NewValue;                 

            }

              public Mode SearchMode
            {
                get { return (Mode)GetValue(SearchModeProperty); }
                set { SetValue(SearchModeProperty, value); }
            }

    }

我希望每次在回调期间设置SearchMode时触发OnIsSearchModeChanged(),即在ViewModel.cs中调用ActivateLastSelectedSearchMode()。我绝对无能为力......在我失踪的地方,我无法取得成功。

3 个答案:

答案 0 :(得分:1)

//snip

    private Mode mSearchMode;
                public Mode SearchMode
                {
                    get
                    {
                        return mSearchMode;
                    }
                    set
                    {
                        mSearchMode = value;
                        NotifyOfPropertyChange(()=>SearchMode); //Change
                 }
                }

反映的变化是否有所不同?其他选项是为您的用户控件创建自定义约定

答案 1 :(得分:1)

您应该在View Model中创建一个Event并从后面的代码订阅它。

在您的视图模型中:

 public event SearchModeAction SearchModeChanged;
 public delegate void SearchModeAction(object sender, EventArgs e);
 public void SearchModeHasChanged()
        {
            SearchModeAction Handler = SearchModeChanged;
            if (Handler != null)
            {
                Handler(this, null);
            }
        }
private void ActivateLastSelectedSearchMode(Mode lastselectedMode)
            {    
               // Sets the last selected mode to the search mode      
                SearchMode =  lastselectedMode;
                SearchModeHasChanged()
            }

在你的守则背后:

 private void Window_Loaded(object sender, RoutedEventArgs e)
        {
           ((YourViewModelClass)DataContext).SearchModeChanged += OnIsSearchModeChanged;
        }

private void OnIsSearchModeChanged(object sender, EventArgs e)
        {
             var searchBox = obj as SearchBox;
             searchBox.SearchMode = (Mode)e.NewValue;         
        }

这样,每次到达View Model中的ActivateLastSelectedSearchMode方法时,都会在视图中调用OnIsSearchModeChanged方法。

答案 2 :(得分:0)

啊......原因是EnumToBooleanConverter。

虽然'parameter'和'value'的值相同,但它们的对象类型之间存在差异,因为它们都引用了不同的命名空间。所以我创建了一个名为“模式”的公共枚举,并确保对同一命名空间的“即时”和“延迟”引用。

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (value == null)
            {
                return false;
            }

            return value.Equals(parameter); // This always returned false despite the values being the same
        }