OnApplyTemplate 从未在自定义控件中调用

问题描述 投票:0回答:2

我测试了一些关于自定义控件的代码,但从未调用过

OnApplyTemplate
。我确信我有正确的静态方法和 assemblyInfo.cs 设置; 包含完整版本。 https://www.dropbox.com/sh/n4uusow5z6ncd9c/AADMrI9jlr-qss7O2qyAg-5Aa?dl=0

public override void OnApplyTemplate()
{
    base.OnApplyTemplate();
    Console.WriteLine("Begin");
    //get the part controls 
    PART_MasterGrid = GetTemplateChild("PART_MasterGrid") as Grid;
    PART_RightCntl = GetTemplateChild("PART_RightCntl") as StackPanel;
    PART_LeftCntl = GetTemplateChild("PART_LeftCntl") as StackPanel;
    PART_BottomCntl = GetTemplateChild("PART_BottomCntl") as StackPanel;
    PART_ParentPanel = GetTemplateChild("PART_ParentPanel") as DockPanel;
    //verify master grid exist
    if (PART_MasterGrid == null)
        return;
    //setup parent grid
    var parentGrid = new Grid();
    SetUpParentGrid(parentGrid);
    //set up layers
    var layer0 = Layers.FirstOrDefault(x => x.Level == 0);
    if (layer0 == null)
        return;

    var columnLayers =
        Layers.Select(x => x).Where(x => x.Level > 0 && x.Orientation == Layer.LayerOrientation.Column).OrderBy(
                x => x.Level);
    var rowLayers =
        Layers.Select(x => x).Where(x => x.Level > 0 && x.Orientation == Layer.LayerOrientation.Row).OrderBy(x => x.Level);
    var item = SetupLayer0(layer0,
                               columnLayers,
                               rowLayers.Count());
    parentGrid.Children.Add(item);
    Grid.SetRow(item, 0);
    //setup the column grid layers
    if (columnLayers.Any())
    {
        foreach (var layer in columnLayers)
        {
            SetupColumnLayers(parentGrid, layer, columnLayers.Count());
        }
    }
    //setup the row grid layers
    if (rowLayers.Any())
    {
        foreach (var layer in rowLayers)
        {
            SetupRowLayers(item, layer, rowLayers.Count());
        }
    }

    //add parent grid to master grid
    PART_MasterGrid.Children.Add(parentGrid);
    Grid.SetRow(parentGrid, 0);
}

更新:我有以下

LayeredGrid.xaml
并有
Generic.xaml
包括
LayeredGrid.xaml

<Style TargetType="{x:Type common:LayeredGrid}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate>
                <DockPanel VerticalAlignment="Stretch" HorizontalAlignment="Stretch" LastChildFill="True"
                           Name="PART_ParentPanel">
                    <StackPanel Name="PART_BottomCnt1" Orientation="Horizontal" DockPanel.Dock="Bottom" Background="AliceBlue"></StackPanel>
                    <StackPanel Name="PART_LeftCnt1" Orientation="Horizontal" DockPanel.Dock="Left" Background="AliceBlue">
                        <StackPanel.LayoutTransform>
                            <RotateTransform Angle="90"/>
                        </StackPanel.LayoutTransform>
                    </StackPanel>
                    <StackPanel Name="PART_RightCnt1" Orientation="Horizontal" DockPanel.Dock="Right" Background="AliceBlue">
                        <StackPanel.LayoutTransform>
                            <RotateTransform Angle="90"/>
                        </StackPanel.LayoutTransform>
                    </StackPanel>
                    <Grid Name="PART_MasterGrid" IsSharedSizeScope="True" Background="AliceBlue"></Grid>
                </DockPanel>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Update2:[Update2 与上述代码无关,因为此版本将 Themes 作为根文件夹] 在

MainWindow.xaml
中给出编译错误无法定位资源“layeredgrid.xaml”。 enter image description here

<DockPanel>
    <StackPanel Name="DownStatusBar" DockPanel.Dock="Bottom" Background="AliceBlue">
        <Label></Label>
    </StackPanel>
    <testNest3:LayeredGrid>
        <testNest3:LayeredGrid.Layers>
            <testNest3:Layer Level="0">
                <testNest3:Layer.Content>
                    <Grid>
                        ...
                    </Grid>
                </testNest3:Layer.Content>
            </testNest3:Layer>
        </testNest3:LayeredGrid.Layers>
    </testNest3:LayeredGrid>
</DockPanel>
wpf custom-controls
2个回答
4
投票

您需要检查一些事项以确保应用默认样式:

  1. 确保您具有程序集级

    ThemeInfo
    属性并传入
    ResourceDictionaryLocation.SourceAssembly
    作为第二个参数 (
    genericDictionaryLocation
    ):

    [assembly: ThemeInfo(
        ResourceDictionaryLocation.None,
        ResourceDictionaryLocation.SourceAssembly)]
    
  2. 确保在与自定义控件相同的程序集中有一个

    Themes\generic.xaml
    资源字典,且构建操作为“Page”。 请注意,
    Themes
    必须是项目中的顶级文件夹。

  3. 确保在静态构造函数中覆盖自定义控件的默认样式键:

    static LayerGrid() {
        DefaultStyleKeyProperty.OverrideMetadata(
            typeof(LayerGrid),
            new FrameworkPropertyMetadata(typeof(LayerGrid)));
    }
    
  4. 确保您的

    generic.xaml
    包含(直接或通过字典合并)一个
    Style
    以及与您的自定义控件匹配的
    TargetType
    。 它不应该有显式的
    x:Key
    ,并且应该设置
    Template
    属性。 如果您通过
    MergedDictionaries
    引入样式,请确保在合并到其他词典时使用程序集限定的 URI,例如:

    <ResourceDictionary Source="/test_nest3;component\Themes/LayeredGrid.xaml" />
    

如果您已验证上述所有内容但仍然遇到问题,请检查输出窗口以确保没有发生某种可能阻止应用样式的错误。 另外,检查显而易见的事情:控件是否实际上已加载到可视化树中的某个位置?


编辑:我能够在手机上打开您的项目,并且您的

Themes
文件夹似乎位于错误的位置:它必须直接位于您的项目下,但您将其嵌套在
Common
文件夹下。 该位置应该相对于程序集根目录,而不是包含定义控件的文件的文件夹。


0
投票

就我而言,解决方案要简单得多:我只是忘了打电话

InitializeComponent()
。 🙄

© www.soinside.com 2019 - 2024. All rights reserved.