wpf_How to binding the parent in ContentPresenter

KarlOKeeffe 20 Reputation points
2023-06-27T06:35:08.12+00:00

hey there;

I have a custom control that passes a TextBox to ContentPresenter through Content in the middle, but I can't bind the text of the TextBox outside,The code is as follows

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApp1">
    <Style TargetType="{x:Type local:MyControl}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:MyControl}">
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition MinWidth="50" Width="3*" />
                            <ColumnDefinition Width="5*" />
                            <ColumnDefinition MinWidth="28" Width="2*"  />
                        </Grid.ColumnDefinitions>
                        <TextBlock Grid.Column="0" Text="{Binding Label}" VerticalAlignment="Center" HorizontalAlignment="Left"/>
                        <ContentPresenter Grid.Column="1" Height="20" ContentSource="InnerContent"/>
                        <TextBlock Grid.Column="2" Text="{Binding Unit}" Margin="5 0 0 0"   VerticalAlignment="Center"  HorizontalAlignment="Left"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>
public class MyControl : Control
{
    static MyControl()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(MyControl), new FrameworkPropertyMetadata(typeof(MyControl)));
    }
    #region DataContext
    public string Label
    {
        get { return (string)GetValue(LabelProperty); }
        set { SetValue(LabelProperty, value); }
    }
    public static readonly DependencyProperty LabelProperty = DependencyProperty.Register("Label", typeof(string), typeof(MyControl), new PropertyMetadata(string.Empty));

    /// <summary>
    /// 单位
    /// </summary>
    public string Unit
    {
        get { return (string)GetValue(UnitProperty); }
        set { SetValue(UnitProperty, value); }
    }
    public static readonly DependencyProperty UnitProperty = DependencyProperty.Register("Unit", typeof(string), typeof(MyControl), new PropertyMetadata(string.Empty));

    public object InnerContent
    {
        get { return (object)GetValue(InnerContentProperty); }
        set { SetValue(InnerContentProperty, value); }
    }
    public static readonly DependencyProperty InnerContentProperty = DependencyProperty.Register("InnerContent", typeof(object), typeof(MyControl));
    #endregion
}
<Window.DataContext>
    <local:MainViewModel x:Name="mydata"/>
</Window.DataContext>
<local:MyControl Label="核定电压" Unit="电流" Height="30" Width="200" HorizontalAlignment="Left" VerticalAlignment="Top">
    <TextBox Text="{Binding ElementName=mydata, Path=InputValue,Mode=TwoWay}" />
</local:MyControl>
<TextBlock Text="{Binding ElementName=mydata, Path=InputValue,StringFormat=[{0}]}" Height="30" Width="200"  HorizontalAlignment="Left" VerticalAlignment="Top"/>

Im pretty lost here because all the stuff you find on the net is with ContentControl or ControlTemplates never found a case with contentpresenter inside a datatemplate that is nested in another contentpresenter.

Developer technologies | XAML
Developer technologies | XAML
A language based on Extensible Markup Language (XML) that enables developers to specify a hierarchy of objects with a set of properties and logic.
Developer technologies | C#
Developer technologies | C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Jiachen Li-MSFT 34,231 Reputation points Microsoft External Staff
    2023-06-28T02:07:13.0366667+00:00

    Hi @Karl Albright .

    Welcome Microsoft Q&A.

    You could update your code as follows.

    With ContentPresenter, most times, this does the job:

    <ContentPresenter /> The default ContentSource is "Content". That means it'll look at the Content property of the templated parent and it'll take whatever it finds there for its own content.

    <StackPanel>
    <local:MyControl Label="Approved voltage" Unit="V" Height="30" Width="200" HorizontalAlignment="Left" VerticalAlignment="Top">
    <local:MyControl.InnerContent>
    <TextBox Text="{Binding InputValue,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"/>
    </local:MyControl.InnerContent>
    
    </local:MyControl>
    
            <TextBlock Text="{Binding  Path=InputValue,StringFormat=[{0}],UpdateSourceTrigger=PropertyChanged}" Height="30" Width="200"  HorizontalAlignment="Left" VerticalAlignment="Top"/>
    </StackPanel>
    
      <Style TargetType="{x:Type local:MyControl}">
    <Setter Property="Template">
    <Setter.Value>
    <ControlTemplate TargetType="{x:Type local:MyControl}">
    <Grid>
    <Grid.ColumnDefinitions>
    <ColumnDefinition MinWidth="50" Width="5*" />
    <ColumnDefinition Width="5*" />
    <ColumnDefinition MinWidth="28" Width="2*"  />
    </Grid.ColumnDefinitions>
    <TextBlock Grid.Column="0" Text="{TemplateBinding Label}" VerticalAlignment="Center" HorizontalAlignment="Left" FontSize="10"  Foreground="Black" />
    
    <ContentPresenter Grid.Column="1" Height="20" Content="{TemplateBinding InnerContent}"/>
    <TextBlock Grid.Column="2" Text="{TemplateBinding Unit}" Margin="5 0 0 0"   VerticalAlignment="Center"  HorizontalAlignment="Left" FontSize="20" Foreground="Black"/>
    </Grid>
    </ControlTemplate>
    </Setter.Value>
    </Setter>
    </Style>
    

    Best Regards.

    Jiachen Li


    If the answer is helpful, please click "Accept Answer" and upvote it.

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    0 comments No comments

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.