21.1K Views
June 01, 23
スライド概要
「.NET の 3 日間 (2 日目) ~3 コミュニティ合同イベント~」で発表した資料です。
https://dotnet-communities.connpass.com/event/277869/
WPFからWinUI 3への 移行チャレンジ その1 2023/6/1 須藤(suusanex)
自己紹介 ID:suusanex( connpass・Twitter・GitHub共通) 名前:須藤圭太 サイエンスパーク株式会社という独立系ソフトウェアベンダーに所属 4年ほど受託開発で、上流から下流まで全部を回す ここ8年ほどは、自社製品開発も担当 Windowsアプリ開発のネタが多い 勉強会もやってます。 https://sciencepark.connpass.com
概要 WPFもGenericHost+MVVMのような構造で作っておけば、Viewだけ作り直せば WinUI 3への移行が容易にできそう という話を、以前のイベントで話しました TemplateStudioのコードを見て、WPFからMAUI(WinUI3)への移行を考える では、Viewの移植は現実的なのか? 1つずつ、できること・できないことを試すしかない まず、割と使うが厄介な点の多い、DataGridを使う画面を試してみた ※WPFからの移行なので、UWPと同じ点も「WPFからWinUI 3への違い」とい う扱いにします
まずはWinUI 3プロジェクトの作成 やり方がだいぶ変遷しているので、最新情報を見ましょう Windows App SDK 用のツールをインストールする 過去にはVS拡張で入れる手順もあり、まだMarketplaceに残っている→古い Template Studioを使う場合も、だいぶ新しくなっているので最新版を Template Studio for WinUI (C#)
見慣れたコントロールがない さっそくDockPanelとDataGridを使おうとすると 無い 見慣れたコントロールの多くは、標準ではなくCommunityToolkit NuGetで入手 CommunityToolkit.WinUI.UI.Controls xaml上では名前空間を指定して使う xmlns:ui="using:CommunityToolkit.WinUI.UI.Controls" <ui:DataGrid></ui:DataGrid>
DockPanel 特に違和感なく、WPFと同じように使える <ui:DockPanel> <TextBlock ui:DockPanel.Dock=“Top” /> </ui:DockPanel>
DataGrid まずはデータ表示
<ui:DataGrid ItemsSource="{Binding DataList}" />
WPFと同じくItemsSourceへのバインドで表示出来る
注意:Template Studioで生成すると、ViewModelをDataContextへ代入する
コードがない
UWPから登場したx:Bindを使う想定のコードになっているので、WPFから移植
する場合は注意
ViewModelをDataContextに入れるコードを足すか、x:Bindで書き直す必要あり
<ui:DataGrid ItemsSource ="{x:Bind ViewModel.DataList}"/>
DataGrid Columnのカスタム
DataGridTextColumnは一通り、WPFと同様に使える
ヘッダ部の文字列
幅の*(割合)指定
幅のMin指定
スタイルの指定(ここではテキスト部の折り返し指定)
<ui:DataGridTextColumn Header="パス" Binding="{Binding FilePath}"
Width="6*" MinWidth="270">
<ui:DataGridTextColumn.ElementStyle>
<Style TargetType="TextBlock">
<Setter Property="TextWrapping" Value="Wrap" />
</Style>
</ui:DataGridTextColumn.ElementStyle>
</ui:DataGridTextColumn>
DataGrid Columnのコンバータ
コンバータも問題なくWPFと同様に使える
IValueConverterの定義のCultureInfoがstringに変わっているが、他は同じ
これもそのままWPFから持ってきて使えると言える
public class DateTimeOneWayConverter : IValueConverter
(略)
<Page.Resources>
<viewModels:DateTimeOneWayConverter x:Key="dateTimeConverter" />
</Page.Resources>
<ui:DataGridTextColumn Header="Date" Binding="{Binding Date, Mode=OneWay,
Converter={StaticResource dateTimeConverter}}" />
DataGridのソート
WPFでは、ヘッダ部分をクリックするとソートする動作がデフォルト実装済み
WinUI 3では、同様の操作はできるが、ソート処理自体は自力で実装
<ui:DataGrid Sorting="Grid_OnSorting">
private void Grid_OnSorting(object? sender, DataGridColumnEventArgs e)
{
var dataGrid = (DataGrid)sender;
ViewModel.SortData(e.Column.Tag.ToString(), true);
e.Column.SortDirection = DataGridSortDirection.Ascending;
(略)
public void SortData(string key, bool isAscending)
//ViewModel
{
ソートは自分で実装
}
まとめ 割と厄介なDataGridを色々試したが、WPFと同等のことができそう xamlをそのまま使えるところも多い そのまま使えないものも、対応付けを理解して書き換えれば使える WPFからWinUI 3への移行、けっこう行けるのでは? 引き続き試していくつもり