繁体   English   中英

WPF子控件继承

[英]WPF Child Control Inheritance

我正在尝试实现一个控件以从 WPF 中继承。

我从来没有使用过 WPF(至少在那个级别)。
所以我需要一些关于如何解决这个问题的最佳实践方向。

我面临的问题是我想要继承的控件有一些需要在控件基类中访问的子控件。
我想在内部使用这些子控件重用该控件,因为它具有从外部填充子控件的功能。
但是由于 WPF 无法使用 xaml 继承控件,因此我无法解决解决方案。

假设我有这个控制权。

<StackPanel x:Class="Framework.UI.Controls.Base.Navigator.NavigatorItem"
             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:Framework.UI.Controls.Base.Navigator"
             mc:Ignorable="d" 
             d:DesignHeight="26" d:DesignWidth="200">
    <Button Name="btnHeader" Content="Button"/>
    <TreeView Name="tvNavContent" Height="0"/>
</StackPanel>

在代码隐藏中,Button 被用于 Click 事件以及标题 Text,我想从继承自 this 的 Control 填充它。

并且通过一个函数,TreeView“tvNavContent”被填充了这样的东西:

<TreeViewItem x:Class="Framework.UI.Controls.Base.Navigator.NavigatorEntry"
             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:Framework.UI.Controls.Base.Navigator"
             mc:Ignorable="d" 
             d:DesignHeight="20" d:DesignWidth="200">
    <TreeViewItem.Header>
        <StackPanel Orientation="Horizontal">
            <Image Name="imgIcon" Width="16" Height="16" Stretch="Fill"/>
            <TextBlock Name="txtTitle"/>
        </StackPanel>
    </TreeViewItem.Header>
</TreeViewItem>

我想要实现的是重用 Stackpanel 与里面的 Button 和 TreeView 以及它的功能。

我尝试了两件事:

首先,我尝试创建一个模板并将其应用于基类。 之后,我只是尝试使用 FindName<>() 函数在基类中加载模板的控件。

这里的问题是,模板是在 InitializeComponent() 之后应用的。
但是在 InitializeComponent() 期间,我已经需要访问权限,为从基类继承的控件设置标题的控件标题属性。

之后我尝试在控件的基类中完全实现子控件。
刚刚在构造函数中创建了它们并将它们添加到基类继承的堆栈面板的 Children 属性中。

那确实(有点)起作用了。
但显然,当这样创建时,控件的行为完全不同。
无论设置如何。 我只是无法让控件正确地适合他们的父母。
此外,在主题调整方面,这种方法完全不适合较大的项目。

有人可以在这里指导我正确的方向吗?

创建一个名为NavigatorItem的类(没有任何.xaml文件):

public class NavigatorItem : Control
{
    static NavigatorItem()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(NavigatorItem),
            new FrameworkPropertyMetadata(typeof(NavigatorItem)));
    }
}

创建一个名为generic.xamlResourceDictionary并将其放在项目根目录下名为themes的文件夹中(这些名称是约定俗成的),并在那里为NavigatorItem类定义一个默认模板:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:WpfApp12">
    <Style TargetType="local:NavigatorItem">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local:NavigatorItem">
                    <StackPanel>
                        <Button Name="btnHeader" Content="Button"/>
                        <TreeView Name="tvNavContent" Height="0"/>
                    </StackPanel>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

然后,您可以覆盖NavigatorItem类的OnApplyTemplate以获取对模板中元素的引用并将事件处理程序连接到它们,例如:

public override void OnApplyTemplate()
{
    Button button = GetTemplateChild("btnHeader") as Button;
    button.Click += Button_Click;
}

private void Button_Click(object sender, RoutedEventArgs e)
{
    MessageBox.Show("button clicked!");
}

暂无
暂无

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

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