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

时间:2014-10-28 12:02:25

标签: wpf custom-controls

我测试了一些有关自定义控件的代码,但从未调用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作为Root文件夹]在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>

1 个答案:

答案 0 :(得分: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" />
    
  5. 如果您已经验证了上述所有内容并且仍然存在问题,请检查输出窗口以确保不会发生某种可能阻止应用该样式的错误。另外,检查一下显而易见的:控件是否实际上被加载到某个可视树中?


    编辑:我能够在手机上打开您的项目,而您的Themes文件夹似乎位于错误的位置:它必须直接在您的项目下,但您有它嵌套在Common文件夹下。该位置应该相对于程序集根目录,而不是包含定义控件的文件的文件夹。