【问题标题】:In WPF is it possible to define a ControlTemplate for a UserControl inside the UserControl itself (without getting warnings/errors in VS)?在 WPF 中,是否可以在 UserControl 本身内部为 UserControl 定义一个 ControlTemplate(而不会在 VS 中收到警告/错误)?
【发布时间】:2015-04-23 08:19:10
【问题描述】:

我有一个用户控件,我想在窗口的某些部分显示不同的控件模板。但我想将这些模板放在 UserControl 本身内(以便更好地维护)。这里是:

<UserControl x:Class="PruebasDeWPF.MyUserControl"
         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:PruebasDeWPF"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
    <ControlTemplate x:Key="UserControlTemplate1" TargetType="local:MyUserControl">
        <Grid>
            <Rectangle Fill="Red"></Rectangle>
        </Grid>
    </ControlTemplate>
    <ControlTemplate x:Key="UserControlTemplate2" TargetType="local:MyUserControl">
        <Grid>
            <Rectangle Fill="Blue"></Rectangle>
        </Grid>
    </ControlTemplate>
</UserControl.Resources>
<Grid>

</Grid>

现在当我使用它时:

<Window x:Class="PruebasDeWPF.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:PruebasDeWPF"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <local:MyUserControl Template="{StaticResource UserControlTemplate1}"></local:MyUserControl>
    </Grid>
</Window>

我在 Visual Studio 中收到错误消息,提示找不到资源并且控件未显示。如果我将模板更改为 DynamicResource,我会收到与警告相同的消息,但控件会显示。无论如何,程序运行良好。那么如何将 UserControl 和它的模板放在一起而不会收到这些烦人的警告/错误呢?我需要一个特定的 ResourceDictionary(另一个文件)吗?

【问题讨论】:

    标签: c# wpf xaml user-controls controltemplate


    【解决方案1】:

    由于资源的加载方式,您尝试使用的模式并不真正适合资源:作为自上而下的树。要在内部定义的选项之间进行切换,最好在UserControl 上定义一个属性(如果你想绑定它,DependencyProperty)可以指示应该使用哪个可用模板。这可以是一个字符串、一个数字或(可能是最好的选项)一个列出可用选项的enum。在您的UserControl 中,您可以根据该值切换使用的内部定义模板。此基本方法用于各种框架控件 - 例如Slider.Orientation

    【讨论】:

    • 好的,所以我添加了一个依赖属性(后面代码中的枚举)和一个样式(在 xaml 中)以根据该属性值更改模板。谢谢!
    【解决方案2】:

    您尝试执行的操作不适用于 UserControl。

    尝试查找有关创建自定义控件的文章。

    基本上,您创建一个新类(只是一个类),继承自 ContentControl,并使用名为“ContentTemplate”的属性,就像在您提供的代码示例中使用“模板”属性一样。

    如果您要在控件中应用任何特定逻辑,请覆盖 OnApplyTemplate 方法

    【讨论】:

      【解决方案3】:

      如果您将模板存储在控件中,那么我认为您不能将其用作静态资源。见:https://msdn.microsoft.com/en-us/library/hh758287.aspx

      尝试将 StaticResource 指定给无法解析的键 在运行时引发 XAML 解析异常。

      在加载期间您的控件不存在,因此模板不存在,因此对模板不存在的键的引用失败。

      DynamicResources 仅在运行时解析,这就是您的程序运行但带有警告的原因。设计器中的警告是说“我现在找不到这个,但在程序运行时可能会找到”。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-11-10
        • 2018-11-23
        • 2013-06-17
        • 1970-01-01
        • 2017-01-23
        • 2015-11-30
        • 2013-04-20
        • 1970-01-01
        相关资源
        最近更新 更多