7

オブジェクトにバインドされたItemsControlがあり、ItemsControlのデータテンプレート内に2つのテキストブロックがあり、最初のテキストブロックのテキストプロパティをこのItemsControlの外側にある別のテキストブロックにバインドしたいと思います。

親データコンテキストでオブジェクトを検索し、Path=TextでTextBlockを検索しようとしました。

一例を以下に示します。

 <TextBlock Name="Name" Text="{Binding Name}"                                                            
     Grid.Column="0"   
     FontSize="{DynamicResource SmallSize}"
     TextWrapping="Wrap"
     TextAlignment="Right"
     Padding="4,0,0,0"
     Grid.ColumnSpan="2" Background="Aqua"/>

     <ItemsControl ItemsSource="{Binding TheValue}"                                                  
         Padding="4,0,0,0" 
         Grid.Column="2"  
         HorizontalAlignment="Right">

         <ItemsControl.ItemTemplate>
             <DataTemplate>
                 <WrapPanel>
                     <TextBlock Text = "{
                           Binding RelativeSource = 
                               {RelativeSource FindAncestor, 
                                AncestorType={x:Type Window}}, Path=Name}"                                                                                                            
                           Grid.Column="0"
                           FontSize="{DynamicResource SmallSize}"
                           TextWrapping="Wrap" ........................
4

1 に答える 1

7
{Binding RelativeSource = {RelativeSource FindAncestor,
                           AncestorType={x:Type Window}}, Path=Name}

ここで、WPFに対して、タイプウィンドウを使用してこのコントロールの最初の親を検索すると言います。たとえば、「ParentWindow」です。このバインディングが発生した後、「ParentWindow」Nameプロパティにバインドされます。

同じXAMLで定義されているコントロールへのバインディングを有効にする場合は、Binding.ElementNameプロパティを使用してソースを明示的に設定できます。これはあなたのコードの例です:

<TextBlock Text = "{Binding ElementName=Name, Path=Text}"/>

ちなみに、コントロール名を「名前」として使うのは良くありません。このコントロールフォームコードを背後で使用すると、Name.Text = "some text"のように見えます。これにより、何が起こっているのかを理解するのに問題が発生する可能性があります。

更新: 異なるデータテンプレートのコントロールDataContextプロパティへのバインドの例

class MainViewModel
{
    public Class1 C1 { get; set; }
    public Class2 C2 { get; set; }

    public MainViewModel()
    {
        C1 = new Class1 { S1 = "This is C1 data context" };
        C2 = new Class2 { S2 = "This is C2 data context" };
    }
}

XAMLの場合:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication1"        
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <DataTemplate DataType="{x:Type local:MainViewModel}">
            <StackPanel>
                <ContentControl Name="cc1" Content="{Binding C1}"/>
                <ContentControl Name="cc2" Content="{Binding C2}"/>
            </StackPanel>
        </DataTemplate>
        <DataTemplate DataType="{x:Type local:Class1}">
            <TextBlock Text="{Binding S1}"/>
        </DataTemplate>
        <DataTemplate DataType="{x:Type local:Class2}">
            <TextBlock Text="{Binding ElementName=cc1, Path=DataContext.C1.S1}"/>
        </DataTemplate>
    </Window.Resources>

    <Grid>
        <ContentControl Content="{Binding}"/>
    </Grid>
</Window>

しかし、私はこのようなものは良いアプローチではないと思います。特に、これはこのDataTemplateで多くのアイテムになる可能性があるためです。たぶん、これをViewModelに委任する必要があります。

于 2012-11-21T16:21:56.957 に答える