web-dev-qa-db-ja.com

WPFデータバインディングの "RelativeSource FindAncestor"は正確には何をしますか?

私は現在、WPFユーザーコントロール内で作業しています(私のXAMLファイルのルート要素は "UserControl"です)。これは、ウィンドウ内でホストされていることがわかります。データバインディングを使用してウィンドウのプロパティにアクセスするにはどうすればよいですか?

なぜ単純に誰かが知っていますか

<Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type Window}}" Path="..." />

動作しません?私が得るエラーメッセージは:

System.Windows.Data警告:4:参照 'RelativeSource FindAncestor、AncestorType =' System.Windows.Window '、AncestorLevel =' 1 ''のバインディングのソースが見つかりません。

編集: ArsenMkrtのアプローチのバリエーションを使用することになったので、彼の答えを受け入れました。ただし、私はまだFindAncestorが「機能しない」理由を見つけることに興味があります。

21
user200783

最善の方法は、UserControlに名前を付けることです

このようにUserControlでバインドするよりも、双方向のバインドでUserControlに依存関係プロパティMyPropertyを作成し、メインウィンドウでバインドします

<UserControl x:Name = "myControl">
     <Label Content={Binding ElementName= myControl, Path=MyProperty}/>
</UserControl>
18
Arsen Mkrtchyan

ItemsControlまたはDataGridViewから「エスケープ」してWindowに到達しようとしている場合、AncestorTypeがx:Type Windowは機能しません。または、少なくともそうではない...

これが当てはまる場合は、おそらくBlendまたはVisual Studioを実行していて、設計時にデータが表示されることを期待しています。これは、VS + Blendの両方が実際にはWindowsではない独自のインスタンスを作成するためです。実行時には問題なく機能しますが、デザインモードでは機能しません。

できることがいくつかあります。

  • UserControlでラップする

  • これが私が思いついた代替ソリューションです。 UserControlまたはWindowを直接参照しないので、親コンテナーを変更してもコードが壊れないという利点があります。

    <Window
    xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
    xmlns:d="http://schemas.Microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:views="clr-namespace:MyWPFApplication.Views"
    xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"                  
    x:Class="MyWPFApplication.Views.UPCLabelPrinterWindow"
    mc:Ignorable="d"
    x:Name="LayoutRoot"
    Title="UPCLabelPrinterWindow">
    
    <views:DataContextWrapper>
        <DockPanel>
            ...
        </DockPanel>
    </views:DataContextWrapper>
    

ここで、DataContextWrapperは単なるグリッドです

namespace MyWPFApplication.Views {
   public class DataContextWrapper : Grid
   {

   }
}

次に、バインドするときにこれを行います:

<TextBlock Text="{Binding="{Binding DataContext.SomeText, 
  RelativeSource={RelativeSource AncestorType={x:Type views:DataContextWrapper}, 
  Mode=FindAncestor}}" />

注:プロパティをWindow自体にバインドする場合は、より扱いにくく、おそらく依存関係プロパティなどを介してバインドする必要があります。しかし、MVVMを使用している場合、これは私が見つけたソリューションの1つです。

4
Simon_Weaver

次のように、Mode = "OneWayToSource"を設定する必要があると思います。

<TextBox Text="{Binding RelativeSource={RelativeSource FindAncestor ,AncestorType={x:Type Grid}},Path=BackGround , Mode=OneWayToSource , UpdateSourceTrigger = PropertyChanged}" />
1
MahmudReza Tari