我测试了一些关于自定义控件的代码,但从未调用过
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”。
<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>
您需要检查一些事项以确保应用默认样式:
确保您具有程序集级
ThemeInfo
属性并传入 ResourceDictionaryLocation.SourceAssembly
作为第二个参数 (genericDictionaryLocation
):
[assembly: ThemeInfo(
ResourceDictionaryLocation.None,
ResourceDictionaryLocation.SourceAssembly)]
确保在与自定义控件相同的程序集中有一个
Themes\generic.xaml
资源字典,且构建操作为“Page”。 请注意,Themes
必须是项目中的顶级文件夹。确保在静态构造函数中覆盖自定义控件的默认样式键:
static LayerGrid() {
DefaultStyleKeyProperty.OverrideMetadata(
typeof(LayerGrid),
new FrameworkPropertyMetadata(typeof(LayerGrid)));
}
确保您的
generic.xaml
包含(直接或通过字典合并)一个 Style
以及与您的自定义控件匹配的 TargetType
。 它不应该有显式的 x:Key
,并且应该设置 Template
属性。 如果您通过 MergedDictionaries
引入样式,请确保在合并到其他词典时使用程序集限定的 URI,例如:
<ResourceDictionary Source="/test_nest3;component\Themes/LayeredGrid.xaml" />
如果您已验证上述所有内容但仍然遇到问题,请检查输出窗口以确保没有发生某种可能阻止应用样式的错误。 另外,检查显而易见的事情:控件是否实际上已加载到可视化树中的某个位置?
编辑:我能够在手机上打开您的项目,并且您的
Themes
文件夹似乎位于错误的位置:它必须直接位于您的项目下,但您将其嵌套在 Common
文件夹下。 该位置应该相对于程序集根目录,而不是包含定义控件的文件的文件夹。
就我而言,解决方案要简单得多:我只是忘了打电话
InitializeComponent()
。 🙄