サーチ…


構文

  • {Binding PropertyName} {Binding Path = PropertyName}に相当します
  • {バインディングパス= SomeProperty.SomeOtherProperty.YetAnotherProperty}
  • {バインディングパス= SomeListProperty [1]}

パラメーター

パラメータ詳細
パスバインドするパスを指定します。指定されていない場合は、DataContext自体にバインドされます。
UpdateSourceTrigger バインド元の値が更新される時期を指定します。デフォルトはLostFocusです。最もよく使用される値はPropertyChangedです。
モード通常OneWayまたはTwoWay 。バインディングによって指定されていない場合は、バインディングターゲットがTwoWayことを要求しない限り、デフォルトでOneWayになりTwoWayTwoWayを使用して読み取り専用プロパティにバインドするときにエラーが発生します。たとえば、読み取り専用文字列プロパティをTextBox.TextにバインドするときにOneWay明示的に設定する必要があります。
ソース現在のDataContextの代わりにStaticResourceをバインディングソースとして使用できるようにします。
RelativeSource 現在のDataContextではなく、バインディングソースとして別のXAML要素を使用できます。
ElementName 現在のDataContextの代わりに名前付きXAML要素をバインディングソースとして使用できるようにします。
FallbackValue バインディングが失敗した場合、この値はバインディングターゲットに提供されます。
TargetNullValue バインディング・ソース値がnull場合、この値はバインディング・ターゲットに提供されます。
コンバータバインディングの値を変換するために使用するコンバータStaticResourceを指定します。たとえば、ブール値をVisibility列挙型アイテムに変換します。
ConverterParameter コンバータに提供されるオプションのパラメータを指定します。この値は静的でなければならず、バインドすることはできません。
StringFormat バインドされた値を表示するときに使用する書式文字列を指定します。
ディレイ (WPF 4.5+)バインディングがViewModel内のBindingSourceを更新する遅延をmillisecondsで指定しmilliseconds 。これをMode=TwoWayにするには、 Mode=TwoWayおよびUpdateSourceTrigger=PropertyChangedを使用する必要があります。

備考

UpdateSourceTrigger

既定では、WPFはコントロールがフォーカスを失ったときにバインディングソースを更新します。ただし、フォーカスを取得できるコントロールが1つしかない場合(例でよく見られるようなもの)、アップデートを動作させるにはUpdateSourceTrigger=PropertyChangedを指定する必要があります。

すべてのキーストロークでバインディングソースを更新するのはコストがかかり、ライブデータの検証が望ましくない場合を除き、多くの双方向バインディングでPropertyChangedをトリガーとして使用したい場合があります。

LostFocusを使用すると残念なことに副作用があります:Enterを押してIsDefaultマークされたボタンを使用してフォームを送信しても、バインディングをバックアップするプロパティは更新されず、変更を効果的に元に戻します。幸いにも、 いくつかの回避策が存在します。

また、UWPとは異なり、WPF(4.5以降)にはバインディングにDelayプロパティがあり、一部のTextBox検証のように、ローカルのみまたは単純なマイナーインテリジェンス設定を持つバインディングには十分であることに注意してください。

ブール値を可視値に変換する

この例では、チェックボックスがIValueConverterを使用してチェックされていない場合、赤いボックス(枠線)が非表示になっています。

注:以下の例で使用されるBooleanToVisibilityConverterは、System.Windows.Controls名前空間にある組み込みの値コンバータです。

XAML:

<Window x:Class="StackOverflowDataBindingExample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <BooleanToVisibilityConverter x:Key="VisibleIfTrueConverter" />
    </Window.Resources>
    <StackPanel>
        <CheckBox x:Name="MyCheckBox"
                  IsChecked="True" />
        <Border Background="Red" Width="20" Height="20"
                Visibility="{Binding Path=IsChecked,ElementName=MyCheckBox, Converter={StaticResource VisibleIfTrueConverter}}" />
    </StackPanel>
</Window>

DataContextの定義

WPFでバインディングを処理するには、 DataContextを定義する必要があります。 DataContextは、デフォルトでデータを取得する場所をバインディングに指示します。

<Window x:Class="StackOverflowDataBindingExample.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:StackOverflowDataBindingExample"
        xmlns:vm="clr-namespace:StackOverflowDataBindingExample.ViewModels"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <vm:HelloWorldViewModel />
    </Window.DataContext>
    ...
</Window>

コードビハインドを使用してDataContextを設定することもできますが、XAML IntelliSenseは多少なりともかわいいことに注意してください。XAMLで厳密に型指定されたDataContextをIntelliSenseで設定して、バインディングに使用できるプロパティを提案する必要があります。

/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new HelloWorldViewModel();
    }
}

より柔軟な方法でDataContextを定義するのに役立つフレームワークがありますが( MVVM Lightにコントロールの反転を使用するビューモデルロケータがあります)、このチュートリアルの目的ではクイックメソッドとダーティメソッドを使用します。

WPFのほとんどすべてのビジュアル要素に対してDataContextを定義できます。 DataContextは、明示的にオーバーライドされている場合を除いて、一般にビジュアルツリー内の祖先から継承されます(例:ContentPresenter内)。

INotifyPropertyChangedの実装

INotifyPropertyChangedは、プロパティが変更されたことをユーザーインターフェイスまたは他のコンポーネントに知らせるために、ソース(つまりDataContext)をバインドする際に使用されるインターフェイスINotifyPropertyChangedPropertyChangedイベントが発生したことをWPFが自動的にUIを更新します。すべてのビューモデルが継承できる基本クラスにこのインタフェースを実装することが望ましいです。

C#6では、これで必要なのは次のとおりです。

public abstract class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void NotifyPropertyChanged([CallerMemberName] string name = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
    }
}

これにより、 NotifyPropertyChangedを2つの異なる方法で呼び出すことができます。

  1. NotifyPropertyChanged()CallerMemberNameという属性のおかげで、呼び出すセッターのイベントを発生させます。
  2. NotifyPropertyChanged(nameof(SomeOtherProperty)) 、これはSomeOtherPropertyのイベントを発生させます。

C#5.0を使用している.NET 4.5以上では、これを代わりに使用できます。

public abstract class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void NotifyPropertyChanged([CallerMemberName] string name = null)
    {
        var handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(name));
        }
    }
}

4.5より前の.NETのバージョンでは、プロパティ名を文字列定数または式を使用して解決する必要があります


注: INotifyPropertyChangedを実装していない "普通の古いC#オブジェクト"(POCO)のプロパティにバインドし、バインディングが期待どおりに機能することを確認することは可能INotifyPropertyChanged 。これは.NETの隠し機能であり、おそらく避けなければなりません。特に、バインディングのModeOneTimeここを参照) OneTime 、メモリリークが発生します。

INotifyPropertyChangedを実装せずにバインディングを更新するのはなぜですか?

別の名前付き要素のプロパティにバインドする

名前付き要素のプロパティにバインドできますが、名前付き要素はスコープ内になければなりません。

<StackPanel>
    <CheckBox x:Name="MyCheckBox" IsChecked="True" />
    <TextBlock Text="{Binding IsChecked, ElementName=MyCheckBox}" />
</StackPanel>

祖先の財産に束縛する

RelativeSourceバインディングを使用すると、ビジュアルツリー内の祖先のプロパティにバインドできます。ビジュアルツリー内の、同じタイプの、または指定したタイプから派生した最も近い最も近いコントロールがバインディングのソースとして使用されます。

<Grid Background="Blue">
    <Grid Background="Gray" Margin="10">
        <Border Background="Red" Margin="20">
            <StackPanel Background="White" Margin="20">
                <Button Margin="10" Content="Button1" Background="{Binding Background, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Grid}}}" />
                <Button Margin="10" Content="Button2" Background="{Binding Background, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type FrameworkElement}}}" />
            </StackPanel>
        </Border>
    </Grid>
</Grid>

この例では、最も近いGrid祖先が灰色の背景を持つため、 Button1は灰色の背景を持っています。 Button2は、白い背景を持っていStackPanel 。これは、 FrameworkElementから派生した最も近い祖先が白いStackPanelです。

RelativeSourceバインディングの例

マルチバインディングで複数の値をバインドする

MultiBindingでは、複数の値を同じプロパティにバインドできます。次の例では、複数の値がTextboxのTextプロパティにバインドされ、StringFormatプロパティを使用して書式設定されています。

<TextBlock>
    <TextBlock.Text>
        <MultiBinding StringFormat="{}{0} {1}">
            <Binding Path="User.Forename"/>
            <Binding Path="User.Surname"/>
        </MultiBinding>
    </TextBlock.Text>
</TextBlock>

StringFormatほかに、 IMultiValueConverter使用して、Bindingsの値をMultiBindingのターゲットの1つの値に変換することもできます。

ただし、MultiBindingをネストすることはできません。



Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow