コードからバインディングを設定する

もくじ
https://tera1707.com/entry/2022/02/06/144447#WinUI3

やりたいこと

普段はxamlに書いたコントロールのプロパティに、<TextBlock Text="{x:Bind ViewModel.MyString, Mode=OneWay}"/>のような感じでバインディングを記述するが、コードの中からバインディングがしたくなった。

どうやればいいか?調べたい。

前提

  • Windows10 Home 21H1 19043.1706
  • VisualStudio2022 Community 17.1.4
  • WinUI3.0
  • Windows App SDK 1.0
  • 2022年6月の時点の調査

やりかた

Microsoft.UI.Xaml.DataBindingクラスを使用する。

やったこと

カラのStackPanelに、C#のコードからTextBlockButtonを追加する。
TextBlockTextプロパティ、ButtonCommandプロパティに、C#コードの中でバインディングを行う、ということをする。

イメージは、

<StackPanel>
    <TextBlock Text="{x:Bind ViewModel.MyString, Mode=OneWay}"/>
    <Button Content="Button" Command="{x:Bind ViewModel.MyCommand}"/>
</StackPanel>

と同じことを、コードの中でやる感じ。

サンプルコード

<Page
    x:Class="PageTemplate.BlankPage2"
    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"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <StackPanel x:Name="stackpanel" />
</Page>
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Data;
using System.ComponentModel;
using System.Diagnostics;

namespace PageTemplate
{
    public sealed partial class BlankPage2 : Page, INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChanged(string propertyName) => this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        // --------------------------------------------------------
        
        private string _myString = "ABC--";
        public string MyString
        {
            get { return _myString; }
            set { _myString = value; OnPropertyChanged(nameof(MyString)); }
        }
        public DelegateCommand MyCommand { get; set; } = new DelegateCommand(() => Debug.WriteLine("Loaded."));

        public BlankPage2()
        {
            this.InitializeComponent();

            var textblock = new TextBlock() ;
            Binding myBinding1 = new Binding();
            myBinding1.Path =    new PropertyPath("MyString");
            myBinding1.Source = this;
            myBinding1.Mode = BindingMode.OneTime;
            textblock.SetBinding(TextBlock.TextProperty, myBinding1);
            stackpanel.Children.Add(textblock);

            var button = new Button() { Content = "ボタン"};
            Binding myBinding2 = new Binding();
            myBinding2.Path = new PropertyPath("MyCommand");
            myBinding2.Source = this;
            myBinding2.Mode = BindingMode.OneTime;
            BindingOperations.SetBinding(button, Button.CommandProperty, myBinding2);
            stackpanel.Children.Add(button);

        }
    }
}

備考

winui3での、C#コードからのBindingのやり方のMS公式ドキュメントがどうしても見つからない...
(2022/06月時点)

参考

How to set a binding in Code?

https://stackoverflow.com/questions/7525185/how-to-set-a-binding-in-code

参考書

WinUI3

WinUI3でアプリを作ろうと思ったときのとっかかりによかった。 msdocsに書いてある情報を、体系的に、順番に読みたいな、というときによいかも。(ただし英語)
この本で分からなかった、かゆいところに手が届かなかった部分を私は記事にしてる感じ。

C#①

表紙に書いてある通り、教科書として最適。 これからC#を勉強したいけど、ネットだけで勉強するのは効率が悪いから体系的に学べる本が欲しいときや、 ちょっとC#を勉強してコード書けるようになったけど、もう少し広く深く知りたいなというときによいと思う。
私は仕事で触れるコードを軸に、基本ネットで断片的にC#を学んだので、その知識の隙間を埋めて枝葉を広げるためにとても分かりやすかった。

C#②

C#の文法的に色々できるのは分かったが、いざ実装するときに、わかったことを使ってどう実装すればいいのか?と悩んだときに指針になりそうな本。
「プロパティ等の名前の付け方、どうすればいい?」「情報をクラス外部に見せるときに、プロパティにすべき?メソッドにすべき?」「異常だと判定したいとき、どんなときにどんな例外をスローすべき?」などなど、勉強になる部分が山ほどあった。
私のように「コードは書くけどこれであってるのか自信がない、レビューで指摘されるのが嫌だ、実装時の(心の)よりどころが欲しい」という人に最適。