简体   繁体   English

在WPF MVVM上单击按钮,如何在命令对视图模型的引用之前或之后让我的视图执行某些操作?

[英]In WPF MVVM on button click how to have my view do something before or after the Command reference to the view model?

On one form I have a Label and an Edit Button. 在一种形式上,我有一个标签和一个编辑按钮。 When the Edit Button is clicked the control template for the label changes to show a TextBox and a Save Button. 单击“编辑按钮”时,标签的控件模板将更改为显示“文本框”和“保存按钮”。 That Save Button is tied to a Save Command on the View Model. 该“保存”按钮与视图模型上的“保存”命令绑定在一起。

My question / problem is, when the Save button is clicked I want it to change the control template back to being a label either before or after the Command Executes on the View Model. 我的问题是,当单击“保存”按钮时,我希望它在视图模型上执行命令之前或之后将控件模板改回为标签。 In my particular case all it needs to do is set a property on my label to True whenever the Save Button is Clicked in addition to the command being executed. 在我特定的情况下,除了执行命令外,每当单击“保存”按钮时,只需将标签上的属性设置为True。

conv:ReadOnlyControlTemplate.DoLock="True"

UPDATE I am much closer now thanks to some of the feedback in answers below. 更新由于以下答案中的一些反馈,我现在更加接近。 I am using the following for the Save Button: 我将以下内容用于“保存”按钮:

<i:Interaction.Triggers>
                                        <ei:DataTrigger Comparison="Equal" Binding="{Binding Test, Converter={StaticResource TestConverter}, NotifyOnTargetUpdated=True, NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}" Value="CommandUpdated"  >
                                            <ei:ChangePropertyAction  PropertyName="conv:ReadOnlyControlTemplate.DoLock" Value="True" TargetObject="{Binding ElementName=ShiftManagerMessages}" /> 
                                        </ei:DataTrigger>
                                    </i:Interaction.Triggers>

Changing to TargetObject from TargetName of the ei:ChangePropertyAction caused it to see the Label correctly. 从ei:ChangePropertyAction的TargetName更改为TargetObject会使它正确看到Label。 However now I get the following error: 但是现在我得到以下错误:

{"Cannot find a property named \\"conv:ReadOnlyControlTemplate.DoLock\\" on type \\"Label\\"."} {“在类型\\“标签\\”上找不到名为\\“ conv:ReadOnlyControlTemplate.DoLock \\”的属性。“}

I can point it to other properties, just not this one and I don't understand why? 我可以将其指向其他属性,但不能指向其他属性,我也不明白为什么?

Not sure if I got the problem correct, but you can run some code behind in your view by subscribing to various (preview)mousedown events of your button and change your layout there. 不确定我是否解决了问题,但是您可以通过订阅按钮的各种(preview)mousedown事件并在其中更改布局,在视图中运行一些代码。 That is, if you have nth against using code behind in an MVVM project. 也就是说,如果您不反对在MVVM项目中使用代码。 Your button will than trigger both the command handler in your VM, and event handler in your view. 然后,您的按钮将同时触发VM中的命令处理程序和视图中的事件处理程序。

<Button MouseDown="Button_MouseDown" Command="{Binding SaveCommand}" />

 private void Button_MouseDown(object sender, System.Windows.RoutedEventArgs e)
 {
    // Set your property
 }

Code behind is an option, but consider what to do if your command fails. 后面的代码是一个选项,但是请考虑如果命令失败,该怎么办。 If you've got a ViewModel there, you can use a data trigger or template selector bound to a property. 如果那里有ViewModel,则可以使用绑定到属性的数据触发器或模板选择器。

I posted an answer last week about how to write a data template selector and bind a control to it... Change View with its ViewModel based on a ViewModel Property 上周,我发布了一个有关如何编写数据模板选择器并将其绑定到控件的答案... 基于ViewModel属性的ViewModel更改视图

Doing this with a DataTrigger - add a reference to Microsoft.Expressions.Interactions, then add the XAML... 使用DataTrigger进行此操作-添加对Microsoft.Expressions.Interactions的引用,然后添加XAML ...

xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" 

in your namespace, then... 然后在您的命名空间中...

<i:Interaction.Triggers>
    <ei:DataTrigger Binding="{Binding ViewModel.State}" Value="CommandUpdated">
         <Setter Property="Foreground" Value="Red" />
    </ei:DataTrigger>
</i:Interaction.Triggers>

This works by triggering based on a property 'State' in the viewmodel. 这是通过基于视图模型中的属性“ State”触发而起作用的。 In this case state is an Enumeration where CommandUpdated is a value of that enum - it could as easily be a bool or int. 在这种情况下,状态为Enumeration,其中CommandUpdated是该枚举的值-它可以很容易地成为bool或int。

An example of using DataTrigger to control template: 使用DataTrigger来控制模板的示例:

<UserControl x:Class="NextPlc.Instore.Epos.Till.UserControl1"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
            xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" 
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
    <ControlTemplate TargetType="Label" x:Key="ReadOnlyTemplate"></ControlTemplate>
    <ControlTemplate TargetType="Label" x:Key="EditTemplate"></ControlTemplate>
</UserControl.Resources>
<i:Interaction.Triggers>
    <ei:DataTrigger Binding="{Binding IsReadOnly}" Value="True">
        <ei:DataTrigger.Actions>
            <ei:ChangePropertyAction TargetName="label" PropertyName="Template" Value="{StaticResource ReadOnlyTemplate}"/>
        </ei:DataTrigger.Actions>
    </ei:DataTrigger>
    <ei:DataTrigger Binding="{Binding IsReadOnly}" Value="False">
        <ei:DataTrigger.Actions>
            <ei:ChangePropertyAction TargetName="label" PropertyName="Template" Value="{StaticResource EditTemplate}"/>
        </ei:DataTrigger.Actions>
    </ei:DataTrigger>
</i:Interaction.Triggers>
<Grid>
    <Label x:Name="label">
    </Label>
</Grid>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM