2

我正在开发 WPF 应用程序并尽我所能遵循 MVVM 架构。我正在为我的所有命令和行为使用 GalaSoft MVVM 光继电器命令实现。

目前,我正在尝试学习和理解附加行为,特别是如何为我的应用程序中的文本块实现附加行为。

我想做的是有一种风格,我可以应用它来选择将执行一些通用命令的文本块(稍后将详细介绍我所说的“通用”)

这是我想做的一个例子。

例如,我有两个窗口。显然在实际应用中我会有更多,但这应该适合我的指导需求。

我想将附加行为应用于这些窗口中的文本块,以实现定义的行为......代码......

主窗口

<Window x:Class="AttachedExample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow"
        Height="350"
        Width="525"
        DataContext="{Binding Source={StaticResource Locator}, Path=Main}">
    <StackPanel>
        <TextBlock  Text="{Binding Path=SomeMainWindowModel.SomeText}" />
    </StackPanel>
</Window>

主窗口视图模型

public class MainWindowViewModel : BaseViewModel
{
    private MainWindowModel _someMainWindowModel = new MainWindowModel();

    public MainWindowModel SomeMainWindowModel
    {
        get
        {
            return this._someMainWindowModel;
        }
        set
        {
            this._someMainWindowModel = value;
            this.NotifyPropertyChange("SomeMainWindowModel");
        }
    }
}

主窗口模型

public class MainWindowModel : BaseModel
{
    private string _someText = "Some main text for Stack Overflow!";

    public string SomeText
    {
        get
        {
            return this._someText;
        }
        set
        {
            this._someText = value;
            this.NotifyPropertyChange("SomeText");
        }
    }
}

现在是辅助窗口....

辅助窗口

<Window x:Class="AttachedExample.SecondaryWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="SecondaryWindow"
        Height="300"
        Width="300"
        DataContext="{Binding Source={StaticResource Locator}, Path=Secondary}">
    <StackPanel>
        <TextBlock  Text="{Binding Path=SomeSecondaryWindowModel.SomeSecondaryText}" />
    </StackPanel>
</Window>

辅助窗口视图模型

public class SecondaryWindowViewModel : BaseViewModel
{
    private SecondaryWindowModel _someSecondaryWindowModel = new SecondaryWindowModel();

    public SecondaryWindowModel SomeSecondaryWindowModel
    {
        get
        {
            return this._someSecondaryWindowModel;
        }
        set
        {
            this._someSecondaryWindowModel = value;
            this.NotifyPropertyChange("SomeSecondaryWindowModel");
        }
    }
}

辅助窗口模型

public class SecondaryWindowModel : BaseModel
{
    private string _someSecondaryText = "Some secondary text for Stack Overflow!";

    public string SomeSecondaryText
    {
        get
        {
            return this._someSecondaryText;
        }
        set
        {
            this._someSecondaryText = value;
            this.NotifyPropertyChange("SomeSecondaryText");
        }
    }
}

我想要做的是能够在资源字典或 App.xaml 中拥有一种样式,我可以将其应用于这些文本块中的每一个。该样式将指定一个附加行为,该行为将使用文本块内容的参数执行一个方法,右键单击。

伪代码

*Right Click text block on MainWindow;*

SomeStaticClass.ExecuteSomeStaticCustomMethod(mainWindowTextBlock.Content.ToString());

*Right Click text block on SecondaryWindow;*

SomeStaticClass.ExecuteSomeStaticCustomMethod(secondaryWindowTextBlock.Content.ToString());

这是一大堆示例代码和解释,用于描述可以通过背后代码中的事件处理程序完成的事情......但这不会遵循 MVVM 模式。

请记住我在您的回复中使用了 MVVM 灯。

4

1 回答 1

0

这可能是您正在寻找的并且符合 MVVM 标准。我使用一种样式将中继命令附加到用户控件内的文本块事件,此用户控件绑定到 MVVM_Light Viewmodel 并具有数据上下文。

<Style x:Key="StyleName" TargetType="{x:Type TextBlock}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TextBlock}">
                <Border x:Name="Bd" SnapsToDevicePixels="true" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}">
                    <ScrollViewer x:Name="PART_ContentHost" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}">
                        <i:Interaction.Triggers>
                            <i:EventTrigger EventName="PreviewMouseRightButtonDown">
                                <cmd:EventToCommand Command="{Binding DataContext.PreviewMouseRightButtonDownCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}"
                                    CommandParameter="{Binding Name, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TextBox}}}"/>
                            </i:EventTrigger>
                        </i:Interaction.Triggers>
                    </ScrollViewer>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

我删除了额外的样式属性以使其更易于阅读。您需要在视图模型中创建一个名为 PreviewMouseRightButtonDownCommand 的字符串类型的命令。然后它将获取文本块名称作为参数。您可以将参数更改为您想要的任何绑定。这样,我想触发此事件命令的任何文本块只需将其样式设置为此 StyleName。

希望这可以帮助

于 2013-04-15T06:11:36.423 回答