如何用WPF实现一个最简单的Mvvm示例

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何用WPF实现一个最简单的Mvvm示例相关的知识,希望对你有一定的参考价值。

创建一个 ViewModelBase

public abstract class ViewModelBase : INotifyPropertyChanged
//属性改变事件
public event PropertyChangedEventHandler PropertyChanged;

//当属性改变的时候,调用该方法来发起一个消息,通知View中绑定了propertyName的元素做出调整
public void RaisePropertyChanged(string propertyName)

PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)

handler(this, new PropertyChangedEventArgs(propertyName));




2创建一个DelegateCommand

public class DelegateCommand : ICommand
readonly Action<object> _execute;
readonly Predicate<object> _canExecute;

public DelegateCommand(Action<object> execute)
: this(execute, null)


public DelegateCommand(Action<object> execute, Predicate<object> canExecute)

if (execute == null)
throw new ArgumentNullException("execute");
_execute = execute;
_canExecute = canExecute;

public void Execute(object parameter)

_execute(parameter);

public bool CanExecute(object parameter)

return _canExecute == null ? true : _canExecute(parameter);

public event EventHandler CanExecuteChanged

add CommandManager.RequerySuggested += value;
remove CommandManager.RequerySuggested -= value;



3创建示例用 ViewModel
让 ViewModel 继承自 ViewModelBase。

public class MainWindowViewModel : ViewModelBase
private string _input;
public string Input

get

return _input;

set

_input = value;
RaisePropertyChanged("Input");



private string _display;
public string Display

get

return _display;

set

_display = value;
RaisePropertyChanged("Display");



public DelegateCommand SetTextCommand get; set;

private void SetText(object obj)

Display = Input;

public MainWindowViewModel()

SetTextCommand = new DelegateCommand(new Action<object>(SetText));



4创建 View
最少只需要三个控件:一个textbox拿来做输入,一个label拿来做输出,一个button拿来提交数据。

<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1.ViewModel"
Title="MainWindow" Height="237" Width="215">
<Grid>
<Button Content="提 交" HorizontalAlignment="Left" Margin="37,137,0,0" VerticalAlignment="Top" Width="75"/>
<TextBox x:Name="tb" HorizontalAlignment="Left" Height="23" Margin="37,30,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/>
<Label HorizontalAlignment="Left" Margin="37,76,0,0" VerticalAlignment="Top" />
</Grid>
</Window>

5绑定 View 和 ViewModel
当 View 和 ViewModel 都已经创建完之后,最后一步就是把它哥俩绑定在一起了。这样,当 View 改变的时候,ViewModel 就会发生相应的改变,反之亦然。
<Grid>
<Button Content="提 交" HorizontalAlignment="Left" Margin="37,137,0,0" VerticalAlignment="Top" Width="75" Command="Binding SetTextCommand"/>
<TextBox x:Name="tb" HorizontalAlignment="Left" Height="23" Margin="37,30,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" Text="Binding Input" />
<Label HorizontalAlignment="Left" Margin="37,76,0,0" VerticalAlignment="Top" Content="Binding Display" />
</Grid>
参考技术A model应该是数据的表示,viewmodel才是业务逻辑一般是在viewmodel层,大多数都使用了实现了此接口的viewmodelbase基类如果你的程序很简单,那通常只需要viewmodel,不需要model层了。如果model不实现(因为有时候model不在你的控制范围之内),只有在ViewModel中封装,而且需要使用哪些属性就要重新让其实现inpc接口,确实比较麻烦。最后,MVVM只是指导原则,不是规定(MVVM is a set of guidelines, not rules.),并没有标准说一定要怎么写的

MVVM 跨 WPF 区域实现

【中文标题】MVVM 跨 WPF 区域实现【英文标题】:MVVM Cross WPF Region Implementation 【发布时间】:2020-07-08 09:26:59 【问题描述】:

我如何用 MVVM Cross 和 WPF 实现这个视图演示;菜单、标签和内容视图?我找不到任何实际示例如何做到这一点。这是一个过时的实现 https://github.com/ThallisonRhanniel/MvvmCross-Samples/tree/master/XPlatformMenus 但我想使用 MvvmCross(6.x) 和 MvvmCross.Platforms.Wpf(6.x)。

主窗口:

[MvxWindowPresentation(Identifier = nameof(MainWindow), Modal = false)]
public partial class MainWindow : MvxWindow<MainWindowViewModel>

菜单:

[MvxContentPresentation(WindowIdentifier = nameof(MainWindow), StackNavigation = true)]
[MvxRegion("MenuContent")]
[MvxViewFor(typeof(MenuViewModel))]
public partial class MenuView

标签栏:

[MvxContentPresentation(WindowIdentifier = nameof(MainWindow), StackNavigation = true)]
[MvxRegion("PageContent")]
[MvxViewFor(typeof(TabViewModel))]
public partial class TabView

使用区域属性;

public class MvxRegionPresentationAttribute : MvxBasePresentationAttribute

    public string RegionName  get; set; 
    public string WindowIdentifier  get; set; 

MainWindow.xaml 内部;

<Frame x:Name="MenuContent"
       Grid.Column="0"
       NavigationUIVisibility="Hidden"></Frame>

<Frame x:Name="PageContent"
       Grid.Column="1"
       NavigationUIVisibility="Hidden"></Frame>

如何在 MVVMCross 6.x 中实现区域?

【问题讨论】:

【参考方案1】:

在搜索了所有 mvvmcross wpf github 项目后,我发现了各种实现,但只有一个更新版本; https://github.com/eiadxp/MvvmCross.Platforms.Wpf.ItemsViewPresenter 它使用 MvvmCross(6.x) 和 MvvmCross.Platforms.Wpf(6.x)。

【讨论】:

以上是关于如何用WPF实现一个最简单的Mvvm示例的主要内容,如果未能解决你的问题,请参考以下文章

WPF MVVM学习

MVVM 跨 WPF 区域实现

WPF MVVM+EF 增删该查 简单示例

WPF MVVM+EF增删改查 简单示例 1对1 映射

我是如何用最简单的前端技术揭示那些灰色产业背后的原理

如何用Java Socket实现一个简单的Redis客户端工具