通过 WPF 中的命令绑定使整个用户控件可单击
Make an entire user control clickable through a command binding in WPF
我想让整个用户控件响应 touch/click 事件。而且,我想通过绑定到命令的视图模型来实现它。
我正在尝试使用户控件的全部内容都可以点击,但我不知道在哪里绑定命令。我知道如何将按钮绑定到命令,但本质上,我希望整个控件都是一个按钮。
这里是用户控件的内容
<Grid x:Name="gridContent1" Margin="5,0,20,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="6*" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions >
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0" Content="{Binding ShortName}" />
<Label Grid.Row="0" Grid.Column="1" Content="{Binding Value}" ContentStringFormat="0.000"/>
<Label Grid.Row="0" Grid.Column="2" Content="{Binding UnitOfMeasurement}" />
<Image Grid.Row="0" Grid.Column="3" Source="{Binding TrendDirection, Converter={StaticResource converterTrendDirection}}" Style="{StaticResource TrendImage}" Width="48" Height="32" HorizontalAlignment="Right" />
</Grid>
这是控件列表绑定到数据后的样子。
我试图让用户单击控件并转到测量的详细图表视图。
视图模型已经定义了一个命令,所以我想绑定到它。
这是使用行为 and/or 触发器的好场景。这是一个使用 Blend 和 BlendSDK 为 WPF 制作的简单示例:
一个用户控件:
<UserControl x:Class="BehaviorSample.MyUserControl"
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:local="clr-namespace:BehaviorSample"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid Background="Red"/>
</UserControl>
视图模型:
使用 System.Windows;
namespace BehaviorSample
{
public class MyViewModel
{
public void SomeMethod() => MessageBox.Show("Hi there!");
}
}
主要windowxaml:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:BehaviorSample"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:MyViewModel/>
</Window.DataContext>
<Grid>
<local:MyUserControl/>
</Grid>
</Window>
然后我们需要将以下命名空间添加到我们的主 window xaml:
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
然后我们更改我们的标记如下:
<Grid>
<local:MyUserControl>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonDown">
<ei:CallMethodAction MethodName="SomeMethod" TargetObject="{Binding Mode=OneWay}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</local:MyUserControl>
</Grid>
我们在这里使用 CallMethodAction 操作,但如果需要,您可以使用自定义行为。
请注意,您可以只手写标记,但您可能想尝试使用 Blend,因为它更容易。
编辑
有几个第三方解决方案可以实现 事件来命令行为 ,例如 MvvmLight、Devexpress WPF 等。但是如果您不想添加额外的依赖项,那么显示的解决方案一定没问题
编辑。使用 MvvmLight EventToCommand 触发动作
主要windowxaml
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:BehaviorSample"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Platform"
x:Class="BehaviorSample.MainWindow"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:MyViewModel />
</Window.DataContext>
<Grid>
<local:MyUserControl>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonDown">
<!--<ei:CallMethodAction MethodName="SomeMethod" TargetObject="{Binding Mode=OneWay}" />-->
<cmd:EventToCommand Command="{Binding Mode=OneWay, Path=SomeCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</local:MyUserControl>
</Grid>
</Window>
注意我们添加了以下命名空间:
xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Platform"
在我们的视图模型中:
public class MyViewModel
{
//public void SomeMethod() => MessageBox.Show("Hi there!");
public RelayCommand SomeCommand => new RelayCommand(() => MessageBox.Show("Hi there!"));
}
我想让整个用户控件响应 touch/click 事件。而且,我想通过绑定到命令的视图模型来实现它。
我正在尝试使用户控件的全部内容都可以点击,但我不知道在哪里绑定命令。我知道如何将按钮绑定到命令,但本质上,我希望整个控件都是一个按钮。
这里是用户控件的内容
<Grid x:Name="gridContent1" Margin="5,0,20,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="6*" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions >
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0" Content="{Binding ShortName}" />
<Label Grid.Row="0" Grid.Column="1" Content="{Binding Value}" ContentStringFormat="0.000"/>
<Label Grid.Row="0" Grid.Column="2" Content="{Binding UnitOfMeasurement}" />
<Image Grid.Row="0" Grid.Column="3" Source="{Binding TrendDirection, Converter={StaticResource converterTrendDirection}}" Style="{StaticResource TrendImage}" Width="48" Height="32" HorizontalAlignment="Right" />
</Grid>
这是控件列表绑定到数据后的样子。
我试图让用户单击控件并转到测量的详细图表视图。
视图模型已经定义了一个命令,所以我想绑定到它。
这是使用行为 and/or 触发器的好场景。这是一个使用 Blend 和 BlendSDK 为 WPF 制作的简单示例:
一个用户控件:
<UserControl x:Class="BehaviorSample.MyUserControl"
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:local="clr-namespace:BehaviorSample"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid Background="Red"/>
</UserControl>
视图模型:
使用 System.Windows;
namespace BehaviorSample
{
public class MyViewModel
{
public void SomeMethod() => MessageBox.Show("Hi there!");
}
}
主要windowxaml:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:BehaviorSample"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:MyViewModel/>
</Window.DataContext>
<Grid>
<local:MyUserControl/>
</Grid>
</Window>
然后我们需要将以下命名空间添加到我们的主 window xaml:
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
然后我们更改我们的标记如下:
<Grid>
<local:MyUserControl>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonDown">
<ei:CallMethodAction MethodName="SomeMethod" TargetObject="{Binding Mode=OneWay}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</local:MyUserControl>
</Grid>
我们在这里使用 CallMethodAction 操作,但如果需要,您可以使用自定义行为。
请注意,您可以只手写标记,但您可能想尝试使用 Blend,因为它更容易。
编辑 有几个第三方解决方案可以实现 事件来命令行为 ,例如 MvvmLight、Devexpress WPF 等。但是如果您不想添加额外的依赖项,那么显示的解决方案一定没问题
编辑。使用 MvvmLight EventToCommand 触发动作
主要windowxaml
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:BehaviorSample"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Platform"
x:Class="BehaviorSample.MainWindow"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:MyViewModel />
</Window.DataContext>
<Grid>
<local:MyUserControl>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonDown">
<!--<ei:CallMethodAction MethodName="SomeMethod" TargetObject="{Binding Mode=OneWay}" />-->
<cmd:EventToCommand Command="{Binding Mode=OneWay, Path=SomeCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</local:MyUserControl>
</Grid>
</Window>
注意我们添加了以下命名空间:
xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Platform"
在我们的视图模型中:
public class MyViewModel
{
//public void SomeMethod() => MessageBox.Show("Hi there!");
public RelayCommand SomeCommand => new RelayCommand(() => MessageBox.Show("Hi there!"));
}