簡體   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