首页 > 解决方案 > 将内容应用于 UserControl 时覆盖 WPF 样式

问题描述

我有一个用于超链接的 UserContol。我需要将按钮的内容动态设置为数据库值。

我查看了此链接 [1]:自定义按钮用户控件样式在设置内容时被覆盖,似乎我拥有该帖子中的大部分内容。但是当我尝试在用户控件中设置内容时出现错误。我不是 WPF 程序员,所以任何简短的帮助将不胜感激。

用户控制

`

<UserControl x:Class="DDC.Controls.LinkButton"
             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" 

             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800"
             x:Name="UserControl">

    <UserControl.Resources>
        <Style x:Key="LinkButtonStyle"    TargetType="{x:Type Button}">
            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlLightLightBrushKey}}"/>
            <Setter Property="Background" Value="{StaticResource ButtonNormalBackground}"/>
            <Setter Property="BorderBrush" Value="{StaticResource ButtonNormalBorder}"/>
            <Setter Property="Cursor" Value="Hand" />
            <Setter Property="Padding" Value="5,0,0,0" />
            <Setter Property="ToolTip" Value="Click to Follow Link" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Button}">
                                                <ContentPresenter 

                                  VerticalAlignment="Top">
                            <ContentPresenter.Resources>
                                <Style TargetType="{x:Type TextBlock}">
                                    <Setter Property="TextDecorations" Value="Underline" />
                                    <Setter Property="TextWrapping" Value="Wrap"/>
                                </Style>
                            </ContentPresenter.Resources>
                        </ContentPresenter>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>

            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="true">
                    <Setter Property="Foreground" Value="LightGray" />
                </Trigger>
            </Style.Triggers>
        </Style>

    </UserControl.Resources>

    <Grid>
        <Button Name ="btnLinkAddress" 
                Style="{DynamicResource LinkButtonStyle}" 
                Content="{Binding Path=Content, RelativeSource={RelativeSource AncestorType={x:Type LinkButton}}}"
                Width="Auto" 
                Height="Auto"  
                UseLayoutRounding="True" 
                Click="LinkButton_Click" >
        </Button>
    </Grid>
</UserControl>

C# 类

public partial class LinkButton : UserControl
    {

        public new static   DependencyProperty ContentProperty =
           DependencyProperty.Register("Content", typeof(object), typeof(LinkButton));

        public new object Content
        {
            get { return (string)GetValue(ContentProperty); }
            set { SetValue(ContentProperty, value); }
        }

        private void LinkButton_Click(object sender, RoutedEventArgs e)
        {
            Button btn = (Button)sender;
            TextBlock tb = (TextBlock)btn.Content;
            Uri uri = new System.Uri(tb.Text);
           // Uri uri = new System.Uri(btn.Content.ToString());

            Process.Start(new ProcessStartInfo(uri.AbsoluteUri));
            e.Handled = true;
        }
        public LinkButton()
        {
            InitializeComponent();
        }

错误

尝试在用户控件中设置内容时出现这些错误

Content="{Binding Path=Content, RelativeSource={RelativeSource AncestorType={x:Type LinkButton}}}"`

Windows Presentation Foundation (WPF) 项目不支持 LinkBut​​ton。

Content="{Binding Path=Content, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"

遍历树时超出逻辑树深度。这可能表明树中有一个循环。

标签: wpfbuttonuser-controls

解决方案


将属性重命名为Content

public partial class LinkButton : UserControl
{
    public static DependencyProperty ButtonContentProperty =
       DependencyProperty.Register("ButtonContent", typeof(object), typeof(LinkButton));

    public object ButtonContent
    {
        get { return (string)GetValue(ButtonContentProperty); }
        set { SetValue(ButtonContentProperty, value); }
    }

    private void LinkButton_Click(object sender, RoutedEventArgs e)
    {
        ...
    }
    public LinkButton()
    {
        InitializeComponent();
    }
}

...并像这样绑定到它:

<Button Name ="btnLinkAddress" 
        Style="{DynamicResource LinkButtonStyle}" 
        Content="{Binding Path=ButtonContent, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
        Width="Auto" 
        Height="Auto"  
        UseLayoutRounding="True" 
        Click="LinkButton_Click" >

如果要将 设置AncestorTypeLinkButton,则应定义命名空间映射:

<Button xmlns:local="clr-namespace:DDC.Controls"
        Name ="btnLinkAddress" 
        Style="{DynamicResource LinkButtonStyle}" 
        Content="{Binding Path=Content, RelativeSource={RelativeSource AncestorType={x:Type local:LinkButton}}}"
        Width="Auto" 
        Height="Auto"  
        UseLayoutRounding="True" 
        Click="LinkButton_Click" >

推荐阅读