Как использовать содержимое WPF ContentControl с DataTemplate

Я скопировал некоторый ресурс о пользовательской кнопке, используя элемент управления содержимым. И я изменил что-то, чтобы быть <TextBlock Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ContentControl},Path=Content}"> для dataTempalte

<DataTemplate x:Key="PriceDataTemplate" DataType="m:ClickTradeViewModel">
    <Button Command="{Binding ExecuteCommand}" Cursor="Hand">
        <Button.Style>
            <Style TargetType="Button">
                <Setter Property="Background" Value="Transparent" />
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="Button">
                            <Border Background="{TemplateBinding Background}">
                                <ContentPresenter Content="{TemplateBinding Content}" />
                            </Border>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
                <Style.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Background" Value="DarkGray" />
                    </Trigger>
                    <Trigger Property="IsPressed" Value="True">
                        <Setter Property="Background" Value="#FF345C8B" />
                    </Trigger>
                    <DataTrigger Binding="{Binding IsExecuting}" Value="True">
                        <Setter Property="Background" Value="DimGray" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </Button.Style>

        <UserControl>
            <UserControl.Template>
                <ControlTemplate TargetType="UserControl">
                    <TextBlock Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ContentControl},Path=Content}"></TextBlock>
                </ControlTemplate>
            </UserControl.Template>
        </UserControl>
    </Button>
</DataTemplate>

И для фактической кнопки он использовал

<ContentControl x:Name="AskContentControl" Grid.Column="2" 
                Margin="5,0,0,0"
                Content="{Binding QQ.Bid}" 
                ContentTemplate="{StaticResource PriceDataTemplate}"/>

Я ожидаю, что Content будет использовать метод tostring double Bid для рендеринга содержимого, но внутри ничего не отображается (серый цвет). На графике левая сторона показывает, что цена существует.

введите здесь описание изображения

Обновление: я не знаю, что происходит, но с некоторыми изменениями <TextBlock Text="{Binding QQ.Ask}"></TextBlock> и установкой

<ContentControl x:Name="AskContentControl" Grid.Column="2" 
                Margin="5,0,0,0"
                Content="{Binding}"
                ContentTemplate="{StaticResource PriceDataTemplate}"/> makes it work. 

Проблема в том, что мне пришлось явно установить PriceDataTemplate несколько раз для разных свойств.


person baozi    schedule 18.11.2014    source источник


Ответы (2)


Это не работает, потому что вы используете Binding с RelativeSource, который находит ContentControl, но UserControl также является ContentControl, поэтому он на самом деле нашел UserControl, а не корень ContentControl, как вы думали. В этом случае вы можете указать некоторые AncestorLevel как 2 (чтобы найти второй ContentControl):

<TextBlock Text="{Binding 
           RelativeSource={RelativeSource Mode=FindAncestor,
                           AncestorType=ContentControl, AncestorLevel=2},
           Path=Content}"></TextBlock>

Однако это не совсем безопасно, и в этом случае неявный DataContext на самом деле является Content, который вы установили для своего ContentControl (этот DataContext вытекает из DataTemplate через шаблон UserControl). Таким образом, привязка может быть такой простой:

<TextBlock Text="{Binding}"></TextBlock>

Примечание. Я полагал, что вы продолжаете устанавливать для ContentControl значение {Binding QQ.Bid}.

person King King    schedule 18.11.2014
comment
Второй простой способ работает! Но использование AncestorLevel приводит только к результату Windows.Controls. - person baozi; 19.11.2014

Это полное рабочее решение... Я опаздываю, но, возможно, это поможет другим?

<UserControl
             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:ParametricStudyAnalysis.ScopeSelection.Special"
             xmlns:xcdg="http://schemas.xceed.com/wpf/xaml/datagrid" x:Class="ParametricStudyAnalysis.ScopeSelection.Special.UserControlAddSpecialSignal"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <UserControl.DataContext>
        <local:UserControlAddSpecialSignalModel></local:UserControlAddSpecialSignalModel>
    </UserControl.DataContext>

    <UserControl.Resources>
        <DataTemplate DataType="{x:Type local:UserControlSpecialSignalTtrModel}">
            <local:UserControlSpecialSignalTtr/>
        </DataTemplate>     
    </UserControl.Resources>

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"></RowDefinition>
            <RowDefinition></RowDefinition>
        </Grid.RowDefinitions>


        <GroupBox Header="Signal type" Grid.Row="0" Padding="5">
            <xcdg:DataGridControl Name="DataGrid" SelectionMode="Single" ItemsSource="{Binding SpecialSignalEntries}"
                              SelectedItem="{Binding SpecialSignalEntrySelected}" Height="200">
            <xcdg:DataGridControl.Columns>
                <xcdg:Column FieldName="Name" Title="Type of special signal" ReadOnly="True"></xcdg:Column>
            </xcdg:DataGridControl.Columns>
        </xcdg:DataGridControl>
        </GroupBox>

        <GroupBox Header="Parameters" Grid.Row="1" Margin="0,3,0,0" Padding="5">
            <ContentControl Name="MyContentControl" 
                            DataContext="{Binding SpecialSignalEntrySelected, Mode=OneWay}" 
                            Content="{Binding SignalProviderSpecial}">
            </ContentControl>
        </GroupBox>
    </Grid>
</UserControl>
person Eric Ouellet    schedule 13.03.2017