[英]How to implement commands on a user control without resorting to code-behind?
[英]How to Implement OnPreviewMouseDown without Code-Behind?
我需要制作代码MVVM(这意味着没有Code-Behind植入 ),并且我想在每次 单击时 更改LabelBackground (即使我单击了按钮)。
这意味着我需要从Code-Behind中删除MainWindowView_OnPreviewMouseDown
和MainWindowView_OnPreviewMouseUp
。
这是我的工作项目:
代码隐藏
public partial class MainWindowView : Window
{
private readonly MainWindowViewModel _viewModel;
public MainWindowView()
{
InitializeComponent();
_viewModel = new MainWindowViewModel();
// The DataContext serves as the starting point of Binding Paths
DataContext = _viewModel;
}
private void MainWindowView_OnPreviewMouseDown(object sender, MouseButtonEventArgs e)
{
_viewModel.LabelBackground = Brushes.Black;
}
private void MainWindowView_OnPreviewMouseUp(object sender, MouseButtonEventArgs e)
{
_viewModel.LabelBackground = Brushes.Blue;
}
}
}
XAML
<Window x:Class="WpfExample.MainWindowView" PreviewMouseDown="MainWindowView_OnPreviewMouseDown" PreviewMouseUp="MainWindowView_OnPreviewMouseUp"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
xmlns:local="clr-namespace:WpfExample">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition/>
</Grid.RowDefinitions>
<Button Grid.Row="0" Command="{Binding HiButtonCommand}" CommandParameter="Hai" Content="click to hi"
Height="100" Margin="208,30,203,30" />
<Label Content="Disco Background" Background="{Binding LabelBackground}" Margin="208,66,203,69" Grid.Row="1"/>
</Grid>
</Window>
视图模型
class MainWindowViewModel : INotifyPropertyChanged
{
private ICommand hiButtonCommand;
public ICommand HiButtonCommand
{
get
{ return hiButtonCommand; }
set
{ hiButtonCommand = value; }
}
private SolidColorBrush labelBackground;
public SolidColorBrush LabelBackground
{
get { return labelBackground; }
set
{
if (labelBackground != value)
{
labelBackground = value;
OnPropertyChanged("LabelBackground");
}
}
}
public MainWindowViewModel()
{
HiButtonCommand = new RelayCommand(ShowMessage);
}
public void ShowMessage(object obj)
{
MessageBox.Show(obj.ToString());
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
最好的方法是什么?
编辑:
我尝试使用
EventTrigger
方法,但对我来说效果不佳,因为它不会更改标签背景,而是在更改窗口背景。 有什么方法可以将标签而不是窗口作为目标?
XAML:
<Window x:Class="WpfExample.MainWindowView" PreviewMouseDown="MainWindowView_OnPreviewMouseDown" PreviewMouseUp="MainWindowView_OnPreviewMouseUp"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
xmlns:local="clr-namespace:WpfExample">
<Window.Triggers>
<EventTrigger RoutedEvent="Mouse.PreviewMouseDown">
<BeginStoryboard>
<Storyboard>
<ColorAnimation To="Black"
Storyboard.TargetProperty="(Label.Background).(SolidColorBrush.Color)"
Duration="0"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="Mouse.PreviewMouseUp">
<BeginStoryboard>
<Storyboard>
<ColorAnimation To="Blue"
Storyboard.TargetProperty="(Label.Background).(SolidColorBrush.Color)"
Duration="0"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Window.Triggers>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition/>
</Grid.RowDefinitions>
<Button Grid.Row="0" Command="{Binding HiButtonCommand}" CommandParameter="Hai" Content="click to hi" Height="100" Margin="208,30,203,30"/>
<Label Name="Label" Content="Disco Background" Background="White" Margin="208,66,203,59" Grid.Row="1"/>
</Grid>
</Window>
我的新XAML解决了该问题,不再需要任何代码隐藏:
新的XAML:
<Window x:Class="WpfExample.MainWindowView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
xmlns:local="clr-namespace:WpfExample">
<Window.Triggers>
<EventTrigger RoutedEvent="Mouse.PreviewMouseDown">
<BeginStoryboard>
<Storyboard>
<ColorAnimation To="Black"
Storyboard.TargetProperty="(Label.Background).(SolidColorBrush.Color)"
Storyboard.TargetName="Label"
Duration="0"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="Mouse.PreviewMouseUp">
<BeginStoryboard>
<Storyboard>
<ColorAnimation To="Blue"
Storyboard.TargetProperty="(Label.Background).(SolidColorBrush.Color)"
Storyboard.TargetName="Label"
Duration="0"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Window.Triggers>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition/>
</Grid.RowDefinitions>
<Button Grid.Row="0" Command="{Binding HiButtonCommand}" CommandParameter="Hai" Content="click to hi" Height="100" Margin="208,30,203,30"/>
<Label Name="Label" Content="Disco Background" Background="White" Margin="208,66,203,59" Grid.Row="1"/>
</Grid>
</Window>
这是一个简单的任务,没有最佳方法。
代码应该是以下几行:
XAML
<Button
cal:Message.Attach="[Event MouseDown] = [Action Action1]"
cal:Message.Attach="[Event MouseUp] = [Action Action2]"
Content="{Binding ButtonContent}" />
<Label
Content="Disco Background"
Background="{Binding Importance, Converter={StaticResource ImportanceToBgConverter}}"/>
视图模型
public String ButtonContent { get; set; } = "click to hi";
public ImportanceType Importance { get; set; }
public void Action1()
{
Importance = Importance.NotImportant;
}
public void Action2()
{
Importance = Importance.Important;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.