DependencyObject不更新View

时间:2017-06-29 07:07:28

标签: c# xaml uwp

我有一个DependencyObject的ViewModel,DependencyProperty未使用新值更新视图。

示例属性(按预期调用get / set包装器)

public static readonly DependencyProperty WeaponNameProperty = DependencyProperty.Register(
        "WeaponName",
        typeof(string),
        typeof(WeaponSystemVM),
        new PropertyMetadata(null, new PropertyChangedCallback(OnWeaponNameChanged)));
    public string WeaponName
    {
        get { return (string)GetValue(WeaponNameProperty); }
        set { SetValue(WeaponNameProperty, value); }
    }

Callback(更改WeaponName时调用)

private static void OnWeaponNameChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    WeaponSystemVM vm = d as WeaponSystemVM;
    if (vm != null)
    { vm.CommandAddWeaponSystem.RaiseCanExecuteChanged(); }
}

CanExecute Delegate(按预期运行并更新相关的Button

private bool CanAddSystem()
{
    if (string.IsNullOrWhiteSpace(WeaponName)) return false;
    if (string.IsNullOrWhiteSpace(WeaponLock)) return false;
    if (string.IsNullOrWhiteSpace(WeaponDamage)) return false;
    if (string.IsNullOrWhiteSpace(WeaponAttack)) return false;
    return true;
}

输入TextBox

<TextBox x:Name="NameInput" Text="{Binding WeaponName, Mode=TwoWay}" Margin="12,4" RelativePanel.Below="NameAdorner" RelativePanel.AlignLeftWithPanel="True"
                     RelativePanel.AlignRightWithPanel="True"/>

输出TextBlock(未使用新值进行更新,DataContext与输入TextBox相同)

<TextBlock Text="{Binding WeaponName}"/>

令人沮丧的是,似乎只是这种实施方式无效 为了重现这个问题,我创建了一个单独的项目,没有与我的应用程序关联的所有额外信息,并且View正在按预期更新。

我不明白的是在这个实现中没有正确完成的事情。 ViewModel正在按预期更新。根据{{​​1}},绑定有效 有人能指出我的问题吗?

1 个答案:

答案 0 :(得分:2)

您不应在ViewModel中使用public abstract class NotifyPropertyChangedBase : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; protected void RaisePropertyChanged([CallerMemberName] string propertyName = null) { this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } protected void SetAndRaiseIfChanged<T>( ref T backingField, T newValue, [CallerMemberName] string propertyName = null) { if (!object.Equals(backingField, newValue)) return; backingField = newValue; this.RaisePropertyChanged(propertyName); } } :它是一个标记类,用于在View端绑定。过度使用并超出了以这种方式使用的范围。
您应该实施INotifyPropertyChanged.PropertyChanged,并在要通知用户界面的每个属性中触发ICommand事件。
类似的东西:

您的ViewModel继承自

private string _weaponName;
public string WeaponName
{
    get { return this._weaponName; }
    set { SetAndRaiseIfChanged(ref this._weaponName, value); }
}

并在您的ViewModel中定义属性,如

private bool CanAddSystem()
{
    return 
        !string.IsNullOrWhiteSpace(WeaponName)
        && !string.IsNullOrWhiteSpace(WeaponLock)
        && !string.IsNullOrWhiteSpace(WeaponDamage)
        && !string.IsNullOrWhiteSpace(WeaponAttack);
}

更简洁的CanAddSystem

<TextBlock Text="{Binding WeaponName}"/>

使用实现gitlab Site接口的东西构建ViewModel命令(类似于RelayCommand)

View片段将是

export default function init_map(some_args) {
...
}

并且您已完成:当您将ICommand绑定到UI时,系统会自动更新从ViewModel读取它的CanExecute。