子の ViewModel のプロパティの更新通知を受け取って、親の View を更新する方法
ViewModel が子として別の ViewModel を持っているパターンというのは結構よくあることだと思いますが、
その際、子の ViewModel のプロパティの更新通知を受け取って親の View を更新したいということもあると思います。
(例えば、リストビューの要素数をステータスバーに表示したい、など。)
これを、できれば XAML の指定のみでやりたいと思って調べて、実際にやってみました。
XAML の記述
まずは、XAML の記述からです。
<Window x:Class="WPF_MVVM.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:WPF_MVVM"
xmlns:local_vm="clr-namespace:WPF_MVVM.ViewModels"
xmlns:local_v="clr-namespace:WPF_MVVM.Views"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local_vm:MainViewModel />
</Window.DataContext>
<Grid>
<Label x:Name="label" Content="{Binding TextBoxViewModel.Text}" HorizontalAlignment="Left" Margin="39,31,0,0" VerticalAlignment="Top"/>
<local_v:TextBoxView x:Name="textBox" HorizontalAlignment="Left" Height="23" Margin="39,82,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" DataContext="{Binding TextBoxViewModel}"/>
<Button x:Name="button" Content="Button" HorizontalAlignment="Left" Margin="53,149,0,0" VerticalAlignment="Top" Width="75" Command="{Binding ButtonCommand}" />
</Grid>
</Window>
<TextBox x:Class="WPF_MVVM.Views.TextBoxView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WPF_MVVM.Views"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
Text="{Binding Text}">
</TextBox>
MainWindow.xaml がウィンドウの XAML、
TextBoxView.xaml が配置しているテキストボックスの XAML です。
ウィンドウには
- ラベル
- テキストボックス
- ボタン
を配置しています。
ラベル、テキストボックスそれぞれに TextBoxViewModel::Text をバインドしています。
ボタンを押すたびに TextBoxViewModel::Text に「True」「False」というテキストが交互に設定され、
それがラベル、テキストボックスの双方に表示される、という仕様になっています。
注目するのはここです。
<local_v:TextBoxView ... DataContext="{Binding TextBoxViewModel}"/>
これは、テキストボックスの DataContext に Window.DataContext.TextBoxViewModel をバインドしています。
こうすることで、子として持っている ViewModel と親の View で配置されているコントロールの DataContext を XAML のみでバインドできます。
C# コードの記述
次に、C# コードの記述です。実装には Livet を使用しています。
using Livet;
using Livet.Commands;
namespace WPF_MVVM.ViewModels
{
// ウィンドウの ViewModel
class MainViewModel : ViewModel
{
// ボタンの Command とバインドしているプロパティ
public ViewModelCommand ButtonCommand
{
get
{
return _ButtonCommand ?? (_ButtonCommand = new ViewModelCommand(ClickButton));
}
}
private ViewModelCommand _ButtonCommand;
// テキストボックスの ViewModel
public TextBoxViewModel TextBoxViewModel
{
get
{
return _TextBoxViewModel;
}
set
{
_TextBoxViewModel = value;
}
}
public TextBoxViewModel _TextBoxViewModel;
// コンストラクタ
public MainViewModel()
{
_TextBoxViewModel = new TextBoxViewModel();
}
// テキスト変更用のフラグ
private bool _Flag = false;
// ボタンを押した時に実行される処理
private void ClickButton()
{
_Flag = !_Flag;
_TextBoxViewModel.Text = _Flag.ToString();
}
}
}
using Livet;
namespace WPF_MVVM.ViewModels
{
// テキストボックスの ViewModel
class TextBoxViewModel : ViewModel
{
// テキストボックスに表示するテキスト
public string Text
{
get
{
return _Text;
}
set
{
_Text = value;
RaisePropertyChanged(nameof(Text));
}
}
private string _Text;
}
}
MainWindowView.cs がウィンドウの ViewModel、
TextBoxViewModel.cs が配置しているテキストボックスの ViewModel です。
データバインドに使用しているプロパティ TextBoxViewModel::Text は自分の更新通知を出しているだけです。
Author And Source
この問題について(子の ViewModel のプロパティの更新通知を受け取って、親の View を更新する方法), 我々は、より多くの情報をここで見つけました https://qiita.com/go_astrayer/items/15f26770cd9d9645e20a著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .