我有一个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}},绑定有效 有人能指出我的问题吗?
答案 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。