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

もくじ
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