我正在编写一个WPF应用程序来学习MVVM设计模式。我是C#和WPF的新手。
我正在尝试在切换ViewModel时传递一些上下文,然后在ICommand实现中使用它来调用方法。但是ICommand在收到上下文后不会更新。
基本上我创建了一个ICommand的实例,按钮绑定到该实例,然后(当传递上下文时)我创建了另一个替换它的实例。
我的问题是:有没有办法重新绑定命令绑定,或者它是初始化时的状态是不可修改的。
我在代码中尝试完成的任务:
Command.cs
public class Command : ICommand
{
public Command(Action action) => this.action = action;
public event EventHandler CanExecuteChanged;
public virtual bool CanExecute(object parameter) => true;
public virtual void Execute(object parameter) => action();
Action action;
}
ObservableObject.cs
public abstract class ObservableObject : INotifyPropertyChanged
{
protected virtual void OnPropertyChanged(string propertyName) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
public event PropertyChangedEventHandler PropertyChanged;
}
FooModel.cs
public class FooModel
{
public int Number => 10;
}
BarModel.cs
public class BarModel
{
public int Number { get; set; }
}
BarViewModel.cs
public class BarViewModel : ObservableObject
{
public BarViewModel()
{
Bar = new BarModel();
BtnCommand = new Command(Reset);
}
public void Receive(object state)
{
if (state is FooModel foo)
{
Counter = Bar.Number = foo.Number;
// this won't reset the number to 10
BtnCommand = new Command(Reset);
// neither will this, why?
Reset();
}
}
public void Reset() => Counter = Bar.Number;
int counter;
public int Counter
{
get => counter;
set
{
counter = value;
OnNotifyPropertyChanged(nameof(Counter));
}
}
Command btnCommand;
public Command BtnCommand
{
get => btnCommand;
set
{
btnCommand = value;
OnNotifyPropertyChanged(nameof(BtnCommand));
}
}
BarModel Bar { get; private set; }
}
BarView.xaml
<UserControl
<! ... namespaces and such -->
>
<UserControl.DataContext>
<local:BarViewModel />
</UserControl.DataContext>
<Grid>
<Button Content="Click" Command="{Binding BtnCommand}"/>
</Grid>
</UserControl>
创建Receive
后调用BarViewModel
方法,并传递FooModel
的实例。当我在if (state ...)
区块内设置断点时,它表示Bar.Number
字段为10,但是当它离开范围时,它会回到0.我感觉这就是它&# #39; s应该工作,但我怎样才能完成Command上下文的更新?
我尝试创建项目的MCVE,这里是指向dropbox的链接。它是使用.NET 4.5.2的VS 2017项目
MCVE中的代码截图:
编辑:更改了文件上传网址
EDIT2:添加了截图
EDIT3:更新的代码
EDIT4:将fileupload更改为dropbox
答案 0 :(得分:3)
您正在BarViewModel
视图中创建Bar
的新实例。删除此XAML标记:
<UserControl.DataContext>
<local:BarViewModel />
</UserControl.DataContext>
然后,应按预期调用在Receive
方法中创建的命令。