0

J'ai une vue qui utilise le contrôle utilisateur SearchBox, La SearchBox a deux boutons radio pour sélectionner les modes de recherche - Instantané et différé. J'ai lié les searchmodes à la propriété SearchMode, et j'ai également créé une propriété de dépendance personnalisée pour le mode de recherche.PropertyChangedCallback ne se déclenche pas pendant le rappel lorsqu'une valeur dans ViewModel est modifiée

Voir

<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); } 
      } 

    } 

Je veux que le OnIsSearchModeChanged() soit déclenché chaque fois que SearchMode est défini pendant le rappel i e, ActivateLastSelectedSearchMode() est appelé dans ViewModel.cs. Je suis absolument désemparé ... où je suis absent, je suis incapable de réussir.

Répondre

1
//snip 

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

Est-ce que le changement reflété fait une différence? Une autre option serait de créer une convention personnalisée pour votre contrôle utilisateur

+0

Merci! J'ai posté ma réponse – user42067

1

Vous devez créer un événement dans votre View Model et vous y abonner à partir de votre code.

Dans votre vue Modèle:

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() 
      } 

votre code Derrière:

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;   
     } 

De cette façon, chaque fois que vous arrivez dans votre méthode de ActivateLastSelectedSearchMode dans votre vue modèle, vous appelez votre méthode OnIsSearchModeChanged dans ta vue.

0

Ahh..la raison était le EnumToBooleanConverter.

Bien que la valeur de 'parameter' et 'value' était la même, il y avait une différence entre leurs types d'objets car les deux faisaient référence à des espaces de noms différents. J'ai donc créé un enum public appelé «Mode» et j'ai assuré que les références «Instant» et «Retardé» au même espace de noms.

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 
     }