gpt4 book ai didi

.net - 如何实现干净的代码隐藏文件?

转载 作者:行者123 更新时间:2023-12-03 10:13:50 25 4
gpt4 key购买 nike

使用 WPF 时,最好让文件后面的 xaml.cs 代码小而干净。 MVVM pattern通过在 ViewModel 类中处理任何业务逻辑的数据绑定(bind)和命令绑定(bind)来帮助实现这一目标。

我正在使用 MVVM 模式的原则,我的代码隐藏文件相当漂亮和干净。任何按钮单击事件都使用命令绑定(bind)来处理,并且还有一些控件也支持命令绑定(bind)。但是,控件上有几个事件没有 Command 和 CommandParameter 属性,因此我看不到使用绑定(bind)的直接方法。摆脱此类事件的代码隐藏文件中的逻辑的最佳方法是什么?例如。处理控件内的鼠标事件。

最佳答案

一个很好的方法是使用 attached behaviour .行为本身可以 Hook 您需要的事件并使用您想要的参数触发适当的命令。它本质上是相同的代码,但它只是将其从您的代码中删除,并让您纯粹在 XAML 中表达您的意图。

CodePlex 上有几个示例行为,或者这是执行命令的基本示例:

using System.Windows;
using System.Windows.Input;
using System.Windows.Interactivity;

/// <summary>
/// Trigger action to execute an ICommand command
/// </summary>
public class ExecuteCommand : TriggerAction<FrameworkElement>
{
#region Dependency Properties

/// <summary>
/// Command parameter
/// </summary>
public static readonly DependencyProperty CommandParameterProperty = DependencyProperty.Register("CommandParameter", typeof(object), typeof(ExecuteCommand), new UIPropertyMetadata(null, OnCommandParameterChanged));

/// <summary>
/// Command to be executed
/// </summary>
public static readonly DependencyProperty CommandProperty = DependencyProperty.Register("Command", typeof(ICommand), typeof(ExecuteCommand), new UIPropertyMetadata(null, OnCommandChanged));

#region Public Properties

/// <summary>
/// Gets or sets the command
/// </summary>
public ICommand Command
{
get
{
return (ICommand)this.GetValue(CommandProperty);
}

set
{
this.SetValue(CommandProperty, value);
}
}

/// <summary>
/// Gets or sets the command parameter
/// </summary>
public object CommandParameter
{
get
{
return (object)this.GetValue(CommandParameterProperty);
}

set
{
this.SetValue(CommandParameterProperty, value);
}
}
#endregion

/// <summary>
/// Executes the command if it is not null and is able to execute
/// </summary>
/// <param name="parameter">This argument not used</param>
protected override void Invoke(object parameter)
{
if (this.Command != null && this.Command.CanExecute(this.CommandParameter))
{
this.Command.Execute(this.CommandParameter);
}
}

/// <summary>
/// Called on command change
/// </summary>
/// <param name="oldValue">old ICommand instance</param>
/// <param name="newValue">new ICommand instance</param>
protected virtual void OnCommandChanged(ICommand oldValue, ICommand newValue)
{
}

/// <summary>
/// Called on command parameter change
/// </summary>
/// <param name="oldValue">old ICommand instance</param>
/// <param name="newValue">new ICommand instance</param>
protected virtual void OnCommandParameterChanged(object oldValue, object newValue)
{
}

/// <summary>
/// Called on command parameter change
/// </summary>
/// <param name="o">Dependency object</param>
/// <param name="e">Dependency property</param>
private static void OnCommandParameterChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
ExecuteCommand invokeCommand = o as ExecuteCommand;
if (invokeCommand != null)
{
invokeCommand.OnCommandParameterChanged((object)e.OldValue, (object)e.NewValue);
}
}

/// <summary>
/// Called on command change
/// </summary>
/// <param name="o">Dependency object</param>
/// <param name="e">Dependency property</param>
private static void OnCommandChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
ExecuteCommand invokeCommand = o as ExecuteCommand;
if (invokeCommand != null)
{
invokeCommand.OnCommandChanged((ICommand)e.OldValue, (ICommand)e.NewValue);
}
}
#endregion
}

}

然后,您可以使用 System.Windows.Interactivity 命名空间(程序集包含在 Blend 3 中)来 Hook 事件并触发命令,如下所示:
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonUp">
<triggers:ExecuteCommand Command="{Binding MyCommand}" CommandParameter="MyParameter" />
</i:EventTrigger>
</i:Interaction.Triggers>

对于具有多个参数的更复杂的事件,您可能需要创建特定的行为,而不是像上面的示例那样使用通用的行为。我通常更喜欢创建自己的类型来存储参数并映射到它,而不是在我的 ViewModel 中有特定的 EventArgs 要求。

*我应该补充的一点是,我绝对不是“代码背后的代码中的 0 代码”那种人,我认为虔诚地执行这一点在某种程度上错过了 MVVM 的意义。只要后面的代码不包含任何逻辑,因此没有真正需要进行测试的代码,那么我就可以忍受后面的一些小代码片段来“弥合 View 和 ViewModel 之间的差距”。如果你有一个“智能 View ”,这有时也是必要的,我通常称之为它,例如浏览器控件,或者你需要从你的 ViewModel 通信的东西。有些人甚至会因为提出这样的建议而受到批评,这就是为什么我把这一点留到最后并首先回答你的问题:-)*

关于.net - 如何实现干净的代码隐藏文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2309622/

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