简体   繁体   English

WPF-ContentPresenter不绑定到UserControl内容

[英]WPF - ContentPresenter does not bind to UserControl Content

Ok, so I'm relatively new to WPF and I'm having a bit of a problem with my usercontrol which contains a custom button. 好的,所以我对WPF比较陌生,而我的usercontrol包含一个自定义按钮存在一些问题。

Everything was working fine until I tried binding the content of the custom button to the usercontrol content. 一切工作正常,直到我尝试将自定义按钮的内容绑定到usercontrol内容。

UserControl Code: 用户控制代码:

<UserControl
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:OP"
mc:Ignorable="d"
x:Class="OP.GamepadButton"
x:Name="GamePadBtn"
d:DesignWidth="100" d:DesignHeight="100">
<UserControl.Resources>
    <Style x:Key="GamepadButtonStyle" TargetType="{x:Type Button}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Grid>
                        <Rectangle x:Name="rectangle" Fill="{TemplateBinding Background}" StrokeThickness="1" Opacity="0.8" Stroke="{TemplateBinding BorderBrush}"/>
                        <ContentPresenter Content="{TemplateBinding Content}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
                        RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" 
                        VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsFocused" Value="True"/>
                        <Trigger Property="IsDefaulted" Value="True"/>
                        <Trigger Property="IsMouseOver" Value="True"/>
                        <Trigger Property="IsPressed" Value="True"/>
                        <Trigger Property="IsEnabled" Value="False"/>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</UserControl.Resources>

<Grid x:Name="LayoutRoot" Background="Transparent">
    <Grid.RowDefinitions>
        <RowDefinition/>
    </Grid.RowDefinitions>
    <Button Content="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:GamepadButton}}, Path=Content}" 
    Background="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:GamepadButton}}, Path=Background}" 
    BorderBrush="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:GamepadButton}}, Path=BorderBrush}" 
    Grid.Row="1" Style="{DynamicResource GamepadButtonStyle}" />
</Grid>

And I declare the usercontrol in my MainWindow the following way: 我通过以下方式在MainWindow中声明用户控件:

<local:GamepadButton Height="60" Width="60" Background="#DAF0FC" BorderBrush="#2c3e50" Content="Button"/>

The result is the following: 结果如下:

结果1

Also, I noticed now that for some reason this also breaks the BorderBrush binding but not the Background binding. 另外,我现在注意到,由于某种原因,这也会破坏BorderBrush绑定,但不会破坏Background绑定。


The code does work if I don't declare any content property for the Usercontrol and set the button Content directly: 如果我没有为Usercontrol声明任何content属性,而是直接设置按钮Content,则代码可以正常工作:

UserControl: 用户控件:

<Button Content="Button" 
    Background="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:GamepadButton}}, Path=Background}" 
    BorderBrush="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:GamepadButton}}, Path=BorderBrush}" 
    Grid.Row="1" Style="{DynamicResource GamepadButtonStyle}" />

MainWindow: 主窗口:

<local:GamepadButton Height="60" Width="60" Background="#DAF0FC" BorderBrush="#2c3e50" />

Which gives me the button style I want: 这给了我想要的按钮样式:

结果2


So my question is. 所以我的问题是。

How do I make the ContentPresenter for the button bind to the content declared for the usercontrol? 如何使按钮的ContentPresenter绑定到为用户控件声明的内容?

The problem you are facing is that you can't bind to content from inside that content. 您面临的问题是您无法从该内容内部绑定到该内容。 Your button inside user control is a current content for control. 用户控件内的按钮是控件的当前内容。 And at your output window you see this lines 在输出窗口中,您会看到以下行

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='OP.GamepadButton', AncestorLevel='1''. BindingExpression:Path=Tag; DataItem=null; target element is 'Button' (Name=''); target property is 'Content' (type 'Object')
System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='OP.GamepadButton', AncestorLevel='1''. BindingExpression:Path=Background; DataItem=null; target element is 'Button' (Name=''); target property is 'Background' (type 'Brush')
System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='OP.GamepadButton', AncestorLevel='1''. BindingExpression:Path=BorderBrush; DataItem=null; target element is 'Button' (Name=''); target property is 'BorderBrush' (type 'Brush')

If you change that to some another property like Tag then your style will applied correctly. 如果将其更改为其他属性(例如Tag),则样式将正确应用。

I think that you can solve your task with using style only, but if you really need new UserControl then you can inherit it directly from button, not UserControl. 我认为您只能使用样式来解决您的任务,但是如果您确实需要新的UserControl,则可以直接从按钮而不是UserControl继承它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM