gpt4 book ai didi

c# - MVVM:实现 ViewModel 的类不更新其模型实例

转载 作者:行者123 更新时间:2023-12-03 10:52:59 24 4
gpt4 key购买 nike

所以我一直在尝试实现 MVVM简单的WPF 中的模式具有以下结构的应用程序:

型号

public class Foobar
{
public string Foo { get; set; }
public string Bar { get; set; }

public string DoSomethingWithFoo()
{
return "The quick brown fox";
}

public string DoSomethingWithBar()
{
return "jumps over the lazy dog.";
}
}

查看模型(基础)
public abstract class ViewModel : INotifyPropertyChanged
{
[Conditional("DEBUG")]
[DebuggerStepThrough]
public void VerifyPropertyName(string propertyName)
{
if (TypeDescriptor.GetProperties(this)[propertyName] == null)
{
Debug.Fail("Invalid property name: " + propertyName);
}
}

protected virtual void OnPropertyChanged(string propertyName)
{
this.VerifyPropertyName(propertyName);

if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}

查看模型 (IMPL)
public class FoobarViewModel : ViewModel
{
private readonly Foobar foobar;

public string Foo
{
get
{
return this.foobar.Foo;
}
set
{
this.foobar.Foo = value;
OnPropertyChanged("Foo");
}
}

public string Bar
{
get
{
return this.foobar.Bar;
}
set
{
this.foobar.Bar = value;
OnPropertyChanged("Bar");
}
}

private FoobarCommand fooCommand;
public FoobarCommand FooCommand
{
get
{
return fooCommand;
}
set
{
fooCommand = value;
OnPropertyChanged("FooCommand");
}
}

private FoobarCommand barCommand;
public FoobarCommand BarCommand
{
get
{
return barCommand;
}
set
{
barCommand = value;
OnPropertyChanged("BarCommand");
}
}

private void DoSomethingWithFoo()
{
if (!string.IsNullOrEmpty(this.foobar.Foo))
{
this.foobar.Foo = this.foobar.DoSomethingWithFoo();
OnPropertyChanged("Foo");
}
}

private void DoSomethingWithBar()
{
if (!string.IsNullOrEmpty(this.foobar.Bar))
{
this.foobar.Bar = this.foobar.DoSomethingWithBar();
OnPropertyChanged("Bar");
}
}

///<remarks>
/// must use the parameterless constructor to satisfy <Window.Resources>
///</remarks>
public FoobarViewModel()
{
this.foobar = new Foobar()
{
Foo = "Lorem",
Bar = "Ipsum"
}

this.fooCommand = new FoobarCommand(DoSomethingWithFoo);
this.barCommand = new FoobarCommand(DoSomethingWithBar);
};
}

命令
public class FoobarCommand : ICommand
{
Action action;

public FoobarCommand(Action action)
{
this.action = action;
}

public bool CanExecute(object parameter)
{
return true;
}

public event EventHandler CanExecuteChanged;

public void Execute(object parameter)
{
this.action.Invoke();
}
}

查看
<Window.Resources>
<local:FoobarViewModel x:Key="FoobarViewModel" />
</Window.Resources>

<Grid DataContext="{StaticResource FoobarViewModel}">

<TextBox Name="FooTextBox" Text="{Binding Foo, Mode=TwoWay, ValidatesOnDataErrors=True}" />
<TextBox Name="BarTextBox" Text="{Binding Bar, Mode=TwoWay, ValidatesOnDataErrors=True}" />

</Grid>

这种方法的问题是,尽管 ViewModelView 绑定(bind)没问题, Model未反射(reflect)此类更改(意味着 Model 未在 ViewModel 处通知其实例的更改)

我真的很感激关于这篇文章的任何建议,在此先感谢你们。

编辑
  • 更新了缺少代码的片段(感谢 Pavlo 和 Ben)
  • 对公共(public) svn 存储库的 promise 解决方案 http://nanotaboada.svn.beanstalkapp.com/dotnet/trunk/Dotnet.Samples.Rijndael/对于任何有兴趣查看整个项目的人。
  • 修改ModelViewModel方法,添加 ICommand执行。如需完整的工作示例,请查看修订版 16。
  • 最佳答案

    除了一个小而重要的细节外,一切看起来都不错。您好像忘记设置 DataContext您的 View 到 View 模型的实例。

    <Window ...
    DataContext="{StaticResource FoobarViewModel}">

    没有它,您的绑定(bind)将失败(在调试器下查看 Visual Studio 的输出窗口,您将看到绑定(bind)错误)。

    另请注意,当 TextBox 出现时, View 模型和模型中的值将更新。失去焦点。在您键入 set UpdateSourceTrigger 时使其更新至 PropertyChanged在您的绑定(bind)上:
    <TextBox Name="FooTextBox" Text="{Binding Foo, Mode=TwoWay, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}" />

    关于c# - MVVM:实现 ViewModel 的类不更新其模型实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5397313/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com