Пользовательский установщик классов не обновляется - PullRequest
0 голосов
/ 17 сентября 2018

У меня есть класс, KeyCombos, который содержит свойство Modifier Keys и Keys:

private ModifierKeys _modifierKeys;
private Key _key;

public ModifierKeys ModifierKeys
{
    get { return _modifierKeys; }
    set
    {
        if (_modifierKeys == value)
            return;

        _modifierKeys = value;
        RaisePropertyChanged(nameof(ModifierKeys));
    }
}

public Key Key
{
    get { return _key; }
    set
    {
        if (_key == value)
            return;

        _key = value;
        RaisePropertyChanged(nameof(Key));
    }
}

public KeyCombo(ModifierKeys modifierKeys, Key key)
{
    Key = key;
    ModifierKeys = modifierKeys;
}

, где RaisePropertyChanged используется для реализации INotifyPropertyChanged.

В моем ViewModel у меня есть свойства, которые связаны с различными комбинациями клавиш, например:

private KeyCombo _firstKeyCombo;
public KeyCombo FirstKeyCombo
{
    get { return _firstKeyCombo; }
    set
    {
        if (_firstKeyCombo == value)
            return;

        _firstKeyCombo = value;
        // Validation method called here
        RaisePropertyChanged(nameof(FirstKeyCombo));
    }
}

И каждая часть KeyCombo установлена ​​в ViewModel, т. Е .:

FirstKeyCombo = new KeyCombo(ModifierKeys.Alt, Key.T);

ViewModel также определяет:

public IEnumerable<Key> Keys => _availableKeys;
ObservableCollection<Key> _availableKey; // set to all available keys
public IEnumerable<ModifierKeys> Modifiers => _modifierKeys;
ObservableCollection<ModifierKeys> _modifierKeys;  // set to all modifier keys

Затем привязывается в View к ComboBoxs:

<StackPanel Orientation="Horizontal" Grid.Row="13" Grid.Column="2">
    <ComboBox ItemsSource="Keys" 
              SelectedItem="{Binding FirstKeyCombo.Key, 
                       Mode=TwoWay, 
                       UpdateSourceTrigger=PropertyChanged}"/>
    <ComboBox ItemsSource="Modifiers" 
              SelectedItem="{Binding FirstKeyCombo.ModifierKey, 
                       Mode=TwoWay, 
                       UpdateSourceTrigger=PropertyChanged}"/>
</StackPanel>

Это работает нормально, соответствующие Key и ModifierKeys отображаются правильно. Мне нужно обновить FirstKeyCombo через установщик, когда изменяется либо Key или ModiferKeys (проверка по all свойств KeyCombo в ViewModel). Очевидно, что моя попытка использовать INotifyPropertyChanged не удалась. Что я должен сделать, чтобы убедиться, что если любое из свойств (ModiferKeys или Keys) изменяется с помощью Combobox, устанавливается FirstKeyCombo?

1 Ответ

0 голосов
/ 17 сентября 2018

В вашей ViewModel вы должны «прослушать» PropertyChanged ваших свойств и установить новый KeyCombo.

Поэтому после создания FirstKeyCombo добавьте PropertyChangedEventhandler

FirstKeyCombo.PropertyChanged += OnFirstKeyComboPropertyChanged;

, который должен выглядетькак это:

private void OnFirstKeyComboPropertyChanged(object sender, PropertyChangedEventArgs e)
{
  //remove the handler
  FirstKeyCombo.PropertyChanged -= OnFirstKeyComboPropertyChanged;
  //create new object because of referential equlity check in WPF
  FirstKeyCombo = new KeyCombo(FirstKeyCombo.ModifierKeys, FirstKeyCombo.Key);
  //add the handler to the new object
  FirstKeyCombo.PropertyChanged += OnFirstKeyComboPropertyChanged;
}

Простого вызова

RaisePropertyChanged(nameof(FirstKeyCombo));

в обработчике событий будет недостаточно, поскольку существует проверка на равенство ссылок, что привело бы к отсутствию нового объекта.

Что касается комментария, то как это будет сделано с Reflection.KeyCombo.Name должно быть именем свойства.

private void OnFirstKeyComboPropertyChanged(object sender, PropertyChangedEventArgs e)
{
  KeyCombo combo = sender as KeyCombo;
  //remove the handler
  combo.PropertyChanged -= OnFirstKeyComboPropertyChanged;
  //create new object because of referential equlity check in WPF
  combo = new KeyCombo(combo.ModifierKeys, combo.Key, combo.Name);
  //add the handler to the new object
  combo.PropertyChanged += OnFirstKeyComboPropertyChanged;
  //Get the ViewModel-Type
  Type t = ViewModel.GetType();
  //Get the property with the name
  PropertyInfo pi = t.GetProperty(combo.Name);
  //set the value of the property
  pi.SetValue(ViewModel,combo);
}

или со словарем.Также KeyCombo.Name должно быть именем свойства.

private void OnFirstKeyComboPropertyChanged(object sender, PropertyChangedEventArgs e)
{
  KeyCombo combo = sender as KeyCombo;
  //remove the handler
  combo.PropertyChanged -= OnFirstKeyComboPropertyChanged;
  //create new object because of referential equlity check in WPF
  combo = new KeyCombo(combo.ModifierKeys, combo.Key, combo.Name);
  //add the handler to the new object
  combo.PropertyChanged += OnFirstKeyComboPropertyChanged;
  dictionaryWithAllCombos[combo.Name] = combo;
  RaisePropertyChanged(combo.Name);
}

в ViewModel

public FirstKeyCombo FirstKeyCombo
{
  get { return dictionary["FirstKeyCombo"]; }
  set 
  { 
    dictionaryWithAllCombos["FirstKeyCombo"] = value; 
    RaisePropertyChanged(nameof(FirstKeyCombo));
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...