もくじ
やりたいこと
.NET6でWPFでアプリを作るときにひな型になるものを作っておきたい。
ついでにやりたいこと
例えばComboBoxの選択項目が変わったときのイベントをMVVMで書くためによく使っていたEventTrigger
を使うときの準備が.NET Framework4.8のときと.NET6でちょっと変わったようなので、それの差し替えもやりたい。
そのやり方はこちらの記事参照。
ざっくり言うとやることは下記。この辺を変える。
- nugetで
Microsoft.Xaml.Behaviors.Wpf
を入れる
(.NETfwでは「System.Windows.Interactivity」のアセンブリへの参照を追加していた) - xamlの頭に「xmlns:i="http://schemas.microsoft.com/xaml/behaviors"」を入れる
(.NETfwでは「http://schemas.microsoft.com/expression/2010/interactivity」だった)
ひな型コード
上にも書いたが、nugetでプロジェクトに Microsoft.Xaml.Behaviors.Wpf
の追加必要。
MainWindow.cs
<Window x:Class="EventTest.MainWindow"
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:EventTest"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<StackPanel>
<ComboBox ItemsSource="{Binding MyComboItemList}" SelectedIndex="{Binding MySelectedIndex}" Height="25">
<!-- .NET6でi:Interaction.Triggers を使うには、 -->
<!-- ①nugetで Microsoft.Xaml.Behaviors.Wpf を入れる -->
<!-- ②xamlの頭に「xmlns:i="http://schemas.microsoft.com/xaml/behaviors"」を入れる -->
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<!-- Eventには、LoadedやSelectionChangedが使える。 -->
<i:InvokeCommandAction Command="{Binding MySelectionChangedCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</ComboBox>
<Button Content="ボタン" Command="{Binding MyButtonChangedCommand}">
</Button>
</StackPanel>
</Window>
MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace EventTest
{
public partial class MainWindow : Window, INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
protected void OnPropertyChanged(string propertyName)
=> this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
// ----------------------------------------------------
// コンボの選択中の項目のindex
public int MySelectedIndex { get; set; }
// コンボボックスの選択変更イベント
public DelegateCommand MySelectionChangedCommand { get; set; }
// ボタン押下イベント
public DelegateCommand MyButtonChangedCommand { get; set; }
private List<string> _myComboItemList = new List<string>() { "aaa", "bbb", "ccc" };
public List<string> MyComboItemList
{
get { return _myComboItemList; }
set { _myComboItemList = value; OnPropertyChanged(nameof(MyComboItemList)); }
}
public MainWindow()
{
InitializeComponent();
DataContext = this;
MySelectionChangedCommand = new DelegateCommand(() =>
{
Debug.WriteLine("選択した項目のindexは {0} です", MySelectedIndex);
});
MyButtonChangedCommand = new DelegateCommand(() =>
{
Debug.WriteLine("ボタンを押しました");
});
}
}
}
DelegateCommand.cs
using System.Windows.Input;
namespace EventTest
{
public class DelegateCommand : ICommand
{
System.Action execute;
System.Func<bool> canExecute;
public bool CanExecute(object parameter)
{
return true;
}
public event System.EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void Execute(object? parameter)
{
execute();
}
public DelegateCommand(System.Action execute)
{
this.execute = execute;
}
public DelegateCommand(System.Action execute, System.Func<bool> canExecute)
{
this.execute = execute;
this.canExecute = canExecute;
}
}
}
※DelegateCommandは以前使っていたものをほぼそのまま使ってる。
なんかnull許容がどうとかの警告?が出てるので、メンテ必要かも。