繁体   English   中英

如何在没有代码隐藏的情况下实现OnPreviewMouseDown?

[英]How to Implement OnPreviewMouseDown without Code-Behind?

我需要制作代码MVVM(这意味着没有Code-Behind植入 ),并且我想在每次 单击时 更改LabelBackground (即使我单击了按钮)。

这意味着我需要从Code-Behind中删除MainWindowView_OnPreviewMouseDownMainWindowView_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>

这是一个简单的任务,没有最佳方法。

  1. 使用fody https://github.com/Fody/Home/并更改属性https://github.com/Fody/PropertyChanged
  2. 创建一个实现通知属性已更改的基类视图
  3. 使用支持MV *模式的框架,例如Caliburn.Micro https://caliburnmicro.com/documentation/cheat-sheet

代码应该是以下几行:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM