C# 如何将附加行为右键单击应用于文本块?
我正在开发一个WPF应用程序,并尽力遵循MVVM体系结构。我使用GalaSoft MVVM light relay命令实现我的所有命令和行为 目前,我正在努力学习和理解附加行为,特别是如何在我的应用程序中为文本块实现附加行为 我想做的是有一个样式,我可以应用于选择执行一些通用命令的文本块(稍后将详细介绍我所说的“通用”的含义) 下面是我想做的一个例子 例如,我有两个窗口。显然,在实际应用中,我会有更多,但这应该适合我的教学需要 我想将附加的行为应用到这些窗口中的文本块,这些文本块将实现定义的行为。。。。代码 主窗口C# 如何将附加行为右键单击应用于文本块?,c#,wpf,.net-4.0,mvvm-light,attachedbehaviors,C#,Wpf,.net 4.0,Mvvm Light,Attachedbehaviors,我正在开发一个WPF应用程序,并尽力遵循MVVM体系结构。我使用GalaSoft MVVM light relay命令实现我的所有命令和行为 目前,我正在努力学习和理解附加行为,特别是如何在我的应用程序中为文本块实现附加行为 我想做的是有一个样式,我可以应用于选择执行一些通用命令的文本块(稍后将详细介绍我所说的“通用”的含义) 下面是我想做的一个例子 例如,我有两个窗口。显然,在实际应用中,我会有更多,但这应该适合我的教学需要 我想将附加的行为应用到这些窗口中的文本块,这些文本块将实现定义的行为
<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>
<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 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");
}
}
}
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");
}
}
}
现在是第二个窗口
辅助窗口
<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>
<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 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");
}
}
}
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 light。这可能是您正在寻找的,并且符合MVVM。我使用一种样式将中继命令附加到textblock事件,该事件位于usercontrol内部,该usercontrol绑定到MVVM_Light Viewmodel并具有datacontext
<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的字符串类型的命令。然后它将获取textblock名称作为参数。可以将参数更改为所需的任何绑定。这样,我想要触发此事件命令的任何文本块只需要将其样式设置为此样式名
希望这有帮助