【WPF】Behaviorの実装方法【MVVM】
Behaviorを実装してみる
WPFのBehaviorってなんかやること多いしXaml側には<i:Interactivity>~...
みたいなよくわからん名前空間がネストしてあるしで何となく敬遠していたのでちゃんと調べました。
あとMVVM的に書きたいけどマウスイベントトリガーでアクションさせたい時どうすればいいのかわからなかったので
チートシート的にまとめました。
世はコードビハインドの記事で溢れかえっている🤕
やりたいこと - 左クリックした時に座標を取得
- Viewでのイベントを検知してViewModelで何かしたい(今回はCanvas上での左クリック)
- Viewのコントロールがもつ値をViewModelに渡したい(今回は左クリックした座標)
コード
CanvasDrawing.xaml
<UserControl x:Class="DrawRectangle.Views.CanvasDrawing"
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:DrawRectangle.ViewModels"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:behaviors="clr-namespace:DrawRectangle.Behaviors"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.DataContext>
<local:CanvasDrawingViewModel/>
</UserControl.DataContext>
<Grid>
<TextBlock Name="Text1"
HorizontalAlignment="Left"
Margin="10,10,0,0"
TextWrapping="Wrap"
Text="{Binding Text.Value}"
VerticalAlignment="Top"
Width="200"/>
<Canvas Name="Canvas1"
Background="#01010101"
Margin="0,37,0,0" >
<i:Interaction.Behaviors>
<behaviors:MouseButtonBehavior MouseLeftButtonClicked="{Binding ClickLeftCommand}"/>
</i:Interaction.Behaviors>
</Canvas>
</Grid>
</UserControl>
CanvasDrawingViewModel.cs
using Reactive.Bindings;
using System.Windows;
namespace DrawRectangle.ViewModels
{
public class CanvasDrawingViewModel
{
public ReactivePropertySlim<string> Text { get; } = new ReactivePropertySlim<string>("クリックされていないな...");
public ReactiveCommand<Point> ClickLeftCommand { get; } = new ReactiveCommand<Point>();
public CanvasDrawingViewModel()
{
ClickLeftCommand.WithSubscribe(p => OnClickLeft(p));
}
private void OnClickLeft(Point p)
{
Text.Value = $"左クリックされたよ! X: {p.X} Y: {p.Y}";
}
}
}
MouseButtonBehavior.cs
using System.Windows;
using System.Windows.Input;
using Microsoft.Xaml.Behaviors;
namespace DrawRectangle.Behaviors
{
public class MouseButtonBehavior : Behavior<FrameworkElement>
{
public static readonly DependencyProperty MouseLeftButtonClickedProperty =
DependencyProperty.Register(
nameof(MouseLeftButtonClicked),
typeof(ICommand),
typeof(MouseButtonBehavior),
new FrameworkPropertyMetadata());
public ICommand MouseLeftButtonClicked
{
get => (ICommand) GetValue(MouseLeftButtonClickedProperty);
set => SetValue(MouseLeftButtonClickedProperty, value);
}
protected override void OnAttached()
{
AssociatedObject.MouseLeftButtonDown += AssociatedObjectOnMouseLeftButtonClicked;
}
private void AssociatedObjectOnMouseLeftButtonClicked(object sender, MouseEventArgs e)
{
AssociatedObject.CaptureMouse();
var prevPoint = e.GetPosition(AssociatedObject);
var point = new Point(prevPoint.X, prevPoint.Y);
if (MouseLeftButtonClicked == null || !MouseLeftButtonClicked.CanExecute(point)) return;
MouseLeftButtonClicked.Execute(point);
}
}
}
おまけ
ネットでBehaviorについて検索しているとSystem.Window.Interactivity
とMicrosoft.Xaml.Behavior
という名前空間が出てきてどう違うんだろうかと思っていましたが、どうもInteractivity
をOSS化したのがXaml.Behavior
みたいです。
Author And Source
この問題について(【WPF】Behaviorの実装方法【MVVM】), 我々は、より多くの情報をここで見つけました https://qiita.com/tkhshiq/items/89b13dc293fb3cd32849著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .