

こんばんは。  
タイトル通りなのですが、XAML内のTextBlockのテキストをビハインドクラス以外の  
別の任意のクラスからバインドすることは可能でしょうか。

あるXAML内のTextBlockのテキストを任意のクラスから書き換えたいです。


CC BY-SA 4.0
2019-08-23T14:19:55.803
57570
2022-07-09T13:06:55.773
35472
question
c# wpf xaml
WPFのxamlでのバインドをビハインドクラス以外に行いたい


XAML内のTextBlockのテキストを任意のクラスからバインドすることは可能です。  
「WPF DataContext Binding」などで検索するとバインディングやMVVMに関するWebページが見つかります。

  * [C# WPFのバインディング その１](https://araramistudio.jimdo.com/2016/11/25/wpf%E3%81%AE%E3%83%90%E3%82%A4%E3%83%B3%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0-%E3%81%9D%E3%81%AE%EF%BC%91/)
  * [WPF MVVM textbox text binding vs changedText event](https://stackoverflow.com/q/20089739)

下記のWpfApp1.csprojのサンプルコードで目的の動作に沿うでしょうか。  
xamlの`UpdateSourceTrigger`を削除すると、ロストフォーカスした時にTextBlockの書き換えが発生します。

`INotifyPropertyChanged`が記述されていないと、ソースからテキストを変更したことをコントロールが感知することができません。  
サンプルコードではTimerを使ってTickメソッドからテキストを変更しています。  
Tickメソッドでコメントアウトされている★のコードを有効にしてもテキストは変わりませんが、`INotifyPropertyChanged`イベントが実装されているとコードからのテキスト変更が反映されます。

MainWindow.xaml:

[code]

    <Window x:Class="WpfApp1.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:WpfApp1"
            mc:Ignorable="d"
            Title="MainWindow" Height="450" Width="800">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
            <StackPanel Grid.Row="0" Name="MyStackPanel">
                <TextBox Text="{Binding SimpleText, UpdateSourceTrigger=PropertyChanged}"/>
                <TextBlock Text="{Binding SimpleText}"/>
            </StackPanel>
            <StackPanel Grid.Row="1">
                <TextBlock Text="{Binding NotifyText}"/>
            </StackPanel>
        </Grid>
    </Window>
    
[/code]

MainWindow.xaml.cs:

[code]

    using System.ComponentModel;
    using System.Threading;
    using System.Windows;
    
    namespace WpfApp1
    {
        /// <summary>
        /// MainWindow.xaml の相互作用ロジック
        /// </summary>
        public partial class MainWindow : Window
        {
            private Timer MyTimer;
            private SimpleModel MySimpleModel = new SimpleModel();
            private NotifyModel MyNotifyModel = new NotifyModel();
    
            public MainWindow()
            {
                InitializeComponent();
    
                MySimpleModel.SimpleText = "ここに入力するとラベルが書き換わります。";
                MyStackPanel.DataContext = MySimpleModel;
                DataContext = MyNotifyModel;
                MyTimer = new Timer(Tick, null, 0, 1000);
    
            }
    
            private void Tick(object state)
            {
                // ★SimpleModelではソースから値を変更しても変わらない(値の変更がxamlに通知されない)
                //MySimpleModel.SimpleText = DateTime.Now.ToString("HH:mm:ss");
    
                // NotifyModelではソースから値を変更すると表示も変更される
                MyNotifyModel.Next();
            }
        }
    
        public class SimpleModel
        {
            public string SimpleText { get; set; }
        }
    
        public class NotifyModel : INotifyPropertyChanged
        {
            public string NotifyText
            {
                get { return Text; }
                set
                {
                    Text = value;
                    OnPropertyChanged(nameof(NotifyText));
                }
            }
            private string Text;
            private int Count = 0;
    
            public void Next()
            {
                Count++;
                Count = (Count > 5) ? 0 : Count;
                NotifyText = new string('■', Count);
            }
    
            public event PropertyChangedEventHandler PropertyChanged;
            protected void OnPropertyChanged(string info)
            {
                if (PropertyChanged == null) return;
                PropertyChanged.Invoke(this, new PropertyChangedEventArgs(info));
                //PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(info));  //C# 6.0以降有効な上記2行の書き換え(Null条件演算子)
            }
        }
    }
    
[/code]


CC BY-SA 4.0
2019-08-30T03:18:25.103
57712
2019-08-30T03:18:25.103
9820
57570
answer