首页 新闻 会员 周边

WPF MVVM使用mvvmlight感觉好啰嗦

0
悬赏园豆:10 [已解决问题] 解决于 2020-07-11 01:07

1.写一个命令处理函数要写一大堆的花花架子,例如

 1        public ICommand WindowCloseCommand
 2         {
 3             get
 4             {
 5                 return new RelayCommand(() =>
 6                 {
 7                          //这里才是自己的代码,外面嵌套的太罗嗦了
 8                 }
 9                 );
10             }
11         }    

 

2.写Model类

1 private string money;
2 
3 public string Money
4 {
5             get { return money; }
6             set { money = value; RaisePropertyChanged(() => Money); }
7 }

 

3.xaml命令比较臃肿

复制代码
1 <i:Interaction.Triggers>
2        <i:EventTrigger EventName="MouseMove">
3                 <i:InvokeCommandAction Command="{Binding xxxCommand}" CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}" />
4         </i:EventTrigger>
5 </i:Interaction.Triggers>
复制代码

 

4.界面涉及复杂的元素操作,例如焦点相关的获取,失去,新开窗体什么的都比较麻烦。有没有那个框架封装度比较高的,能解决这些问题。例如vue的双向绑定就很简约。

屋檐不懂雨的主页 屋檐不懂雨 | 初学一级 | 园豆:27
提问于:2020-01-03 15:13
< >
分享
最佳答案
0

没错,即使使用了 mvvm 框架,该模式还是显得繁琐,mvvm 模式很重要的优点是单元测试,如果项目小,其实没啥使用的必要,爱怎么写怎么写。

不过还是有解决方法的!

Q:如何消除 Model 中繁琐的属性通知代码?

A:使用 Fody 旗下的 Fody/ropertyChanged

基本使用方法:在 Model 类名上添加  [AddINotifyPropertyChangedInterface]  特性,该类的所有属性便全部拥有了通知功能。

 

Q:如何消除命令模式前后端的繁琐代码?

A:mvvm 框架 Caliburn.Micro 也许能帮你,该框架与 mvvmlight 不同,它基于名称约定,也就是说,如果你有个名为 “GetData” 的按钮,vm 中有个名为 “GetData()” 的方法,那么这个按钮就自动将命令绑定到了 GetData() 方法。

另一个推荐的 mvvm 框架是 Stylet,它是由 Caliburn.Micro 改造而来,提供了更多简化操作。

补充推荐一个 mvvm 框架:Catel,也具有自动映射从模型到视图模型的功能。

 

以上具体使用方法,可以自行搜索教程。

收获园豆:10
CodingNinja | 初学一级 |园豆:157 | 2020-07-09 14:33

非常感谢,我去试试

屋檐不懂雨 | 园豆:27 (初学一级) | 2020-07-09 14:37

你好,stylet怎么实现事件转命令呢,mvvmlight中可以使用cmd命名空间的eventtocommand,stylet中怎么响应例如textbox的keyup,mousedown之类的事件呢

屋檐不懂雨 | 园豆:27 (初学一级) | 2020-07-16 13:32

@屋檐不懂雨: 命令和事件都一样:

<Button Command="{s:Action DoSomething}" CommandParameter="Hello">Click me</Button>
public void DoSomething() { }

public void DoSomething(EventArgs e) { }
 
public void DoSomething(object sender, EventArgs e) { }
CodingNinja | 园豆:157 (初学一级) | 2020-07-16 15:40

@CodingNinja: 不是这种,例如textbox我想要在keydown事件中获取按下键的字符信息,这种要怎么写,直接传参会的

屋檐不懂雨 | 园豆:27 (初学一级) | 2020-07-16 15:42

@CodingNinja: 尝试了下这样写,但是发现按字母键无法触发keydown事件,只有ctrl,shift,alt能触发

<TextBox
     Margin="307,61,285.6,310"
     KeyDown="{s:Action keydown}"
     Text="{Binding UserModel.UserPwd}" />
屋檐不懂雨 | 园豆:27 (初学一级) | 2020-07-16 15:51

@屋檐不懂雨: 你后台事件处理函数怎么写的?

CodingNinja | 园豆:157 (初学一级) | 2020-07-16 15:53

@CodingNinja: 

public void keydown(object sender, KeyEventArgs e)
{

}
屋檐不懂雨 | 园豆:27 (初学一级) | 2020-07-16 16:12

@屋檐不懂雨: 不得而知,试试 PreviewKeyDown 事件

CodingNinja | 园豆:157 (初学一级) | 2020-07-16 16:47

@CodingNinja: 试过了,也不行.如果这样的话其实stylet框架并不成熟,windows上的稍微复杂点的操作都没法搞呀,或者复杂操作不用stylet

屋檐不懂雨 | 园豆:27 (初学一级) | 2020-07-16 16:50

@屋檐不懂雨: 我帮你在 GitHub 问了,等结果吧。

CodingNinja | 园豆:157 (初学一级) | 2020-07-16 16:57

@CodingNinja: 好的,多谢

屋檐不懂雨 | 园豆:27 (初学一级) | 2020-07-16 16:59

@屋檐不懂雨: 但是,你为什么需要 KeyDown 事件?

CodingNinja | 园豆:157 (初学一级) | 2020-07-16 17:01

@CodingNinja: 

有时候要对用户输入的东西做些判断处理,例如一个textbox金额框,不能输入非法字符之类的.还有一些特殊的操作会需要mousedown,mouseup之类的事件

屋檐不懂雨 | 园豆:27 (初学一级) | 2020-07-16 17:28

@屋檐不懂雨: wpf 有很多数据校验方式,不需要 KeyDown 啊,比如你可以把绑定触发模式设置为 UpdateSourceTrigger=PropertyChanged ,发生变化就触发判断。

CodingNinja | 园豆:157 (初学一级) | 2020-07-16 17:34

@CodingNinja: 公司做的程序是那种工具类的,操作交互比较复杂,不是单纯的界面展示数据.还有一些mousedown,mouseup触发的事件都比较多

屋檐不懂雨 | 园豆:27 (初学一级) | 2020-07-17 09:19
其他回答(4)
0

问题尖锐奥,插眼

猝不及防 | 园豆:2831 (老鸟四级) | 2020-01-03 15:37

我在看aop的时候看到了一种aop的写法:

 [Mixin(typeof(INotifyPropertyChanged))]
 [Aspect(Scope.PerInstance)]
 internal class NotifyAspect : INotifyPropertyChanged
 {
    public event PropertyChangedEventHandler PropertyChanged = (s, e) => { };

    [Advice(Kind.After, Targets = Target.Public | Target.Setter)]
    public void AfterSetter(
        [Argument(Source.Instance)] object source,
        [Argument(Source.Name)] string propName,
        [Argument(Source.Injections)] Attribute[] injections
        )
    {
        PropertyChanged(source, new PropertyChangedEventArgs(propName));

        foreach(var i in injections.OfType<Notify>().ToArray())
            PropertyChanged(source, new PropertyChangedEventArgs(i.NotifyAlso));
    }
}

对应的属性就可以简单些了:

  [Notify(NotifyAlso = nameof(Fullname))]
    public string FirstName
    {
        get; 
        set;
    }

    [Notify(NotifyAlso = nameof(Fullname))]
    public string LastName 
    {
        get; 
        set;
    }
支持(0) 反对(0) 猝不及防 | 园豆:2831 (老鸟四级) | 2020-01-14 08:49
0

MouseMove需要事件转命令,按钮啥的并不需要这么麻烦。我们都没用过什么框架,自己稍微封装了下。

会长 | 园豆:12459 (专家六级) | 2020-01-03 15:39

只有个别控件有command命令,其他大部分控件都要这样写

支持(0) 反对(0) 屋檐不懂雨 | 园豆:27 (初学一级) | 2020-01-03 16:17
0

Button_Click

日暮青色 | 园豆:495 (菜鸟二级) | 2020-01-04 16:37
0

事件绑定命令确实代码冗余,可以试试自定义Behavior或MarkupExtension,这是源代码:https://github.com/LeoYang-Chuese/wif ,比Blend的方式要简单。

第一种:EventToCommandBehavior。

<Wif.Demo:ListBox x:Name="ListBox" ItemsSource="{Binding ListBoxItems}"> 
<wif:EventToCommandBehavior.EventBindings> 
<Wif:EventBinding Command = "{Binding CustomCommand}" EventName="MouseEnter" /> 
</Wif:EventToCommandBehavior.EventBindings> 
</Wif.Demo:ListBox> 

第二种:EventBindingExtension。

<Rectangle MouseDown="{wif:EventBinding MouseDownCommand}" /> 普通无参数绑定。
<Rectangle MouseDown="{wif:EventBinding Command=MouseDownCommand, CommandParameter=blue}" /> 普通绑定。
<Rectangle MouseDown="{wif:EventBinding Command=MouseDownCommand, CommandParameter=$this.Fill}" /> 绑定到当前控件的属性上。
<Rectangle MouseDown="{wif:EventBinding Command=MouseDownCommand, CommandParameter=$e}" />  绑定到当前上下文上。
楚人Leo | 园豆:803 (小虾三级) | 2020-01-16 15:22

你好,那eventtocommand怎么写呢,vm中怎么接收事件参数呢

支持(0) 反对(0) 屋檐不懂雨 | 园豆:27 (初学一级) | 2020-07-16 16:52

@屋檐不懂雨:
第一种:

<Wif.Demo:ListBox x:Name="ListBox" ItemsSource="{Binding ListBoxItems}"> 
    <wif:EventToCommandBehavior.EventBindings> 
        <Wif:EventBinding Command = "{Binding CustomCommand}" 
                          EventName="MouseEnter"
                          CommandParameter="MyParameter"/> 
    </Wif:EventToCommandBehavior.EventBindings> 
</Wif.Demo:ListBox> 

第二种方式是自定义的,如你所见,某些参数前面需要加 $ 符号。

支持(0) 反对(0) 楚人Leo | 园豆:803 (小虾三级) | 2020-07-21 09:33
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册