在WPF中,是否可以在UserControl本身内为UserControl定义ControlTemplate(不会在VS中收到警告/错误)?

时间:2015-04-23 08:19:11

标签: c# wpf xaml user-controls controltemplate

我有一个UserControl我希望在窗口的某些部分显示不同的控件模板。但我希望将这些模板保存在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(另一个文件)吗?

3 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:0)

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

尝试查找文章以创建CustomControls。

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

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

答案 2 :(得分:0)

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

  

尝试将StaticResource指定为无法解析的密钥   在运行时抛出XAML解析异常。

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

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