110,533
社区成员
发帖
与我相关
我的任务
分享
<UserControl x:Class="WPF3.UserControl1"
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"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid Background="#FFC11D1D"/>
</UserControl>
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
this.Height = 100;
this.Width = 100;
}
}
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WPF3">
<Style TargetType="{x:Type local:CustomControl1}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:CustomControl1}">
<Border>
<local:UserControl1 Width="2"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
<Window x:Class="WPF3.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WPF3"
Title="MainWindow" Height="350" Width="525">
<Grid>
<local:CustomControl1/>
</Grid>
</Window>
<Window x:Class="WPF3.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WPF3"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Style x:Key="aa" TargetType="Control">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Border>
<local:UserControl1 Width="2"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<StackPanel>
<Control Style="{StaticResource aa}"/>
<local:UserControl2/>
</StackPanel>
</Grid>
</Window>
<UserControl x:Class="WPF3.UserControl2"
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:WPF3"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<local:UserControl1 Width="2"/>
</Grid>
</UserControl>
<Window x:Class="WPF3.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WPF3"
Title="MainWindow" Height="350" Width="525">
<Grid>
<StackPanel>
<local:CustomControl1/>
<local:UserControl2/>
</StackPanel>
</Grid>
</Window>
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
<StackPanel>
<Control Name="myControl" />
</StackPanel>
</Window>
using System.Windows;
using System.Windows.Controls;
using System.Windows.Markup;
using System.Windows.Media;
namespace WpfApplication1
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.Title = "鼠标点击,显示几种模板的效果[无,代码模板,xaml模板]";
ControlTemplate[] templates = { null, CreateTemplateCode(), CreateTemplateXaml() };
int i = 0;
this.MouseDown += delegate { myControl.Template = templates[++i % templates.Length];};
}
ControlTemplate CreateTemplateCode()
{
var borderFactory = new FrameworkElementFactory(typeof(Border)); // <Border>
var userControl1Factory = new FrameworkElementFactory(typeof(UserControl1)); // <local:UserControl1
borderFactory.SetValue(Border.BackgroundProperty, Brushes.Yellow); // 代码方式额外改变Border的背景,以便区别
userControl1Factory.SetValue(UserControl1.WidthProperty, 2.0); // Width="2" />
borderFactory.AppendChild(userControl1Factory);
ControlTemplate controlTemplate = new ControlTemplate(typeof(Control));
controlTemplate.VisualTree = borderFactory;
return controlTemplate;
}
ControlTemplate CreateTemplateXaml()
{
string xaml = string.Format(
@"<ControlTemplate TargetType='Control' xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'>
<Border>
<local:UserControl1 Width='2' xmlns:local='clr-namespace:{0};assembly={1}'/>
</Border>
</ControlTemplate>",
typeof(UserControl1).Namespace,
typeof(UserControl1).Assembly.GetName().Name);
return (ControlTemplate)XamlReader.Parse(xaml);
}
}
// 可以不需要另外的UserControl1.xaml
public class UserControl1 : UserControl
{
public UserControl1()
{
this.Background = Brushes.Red;
this.Height = 100;
this.Width = 100;
}
}
}
FrameworkElementFactory borderFactory = new FrameworkElementFactory(typeof(Border)); // <Border>
FrameworkElementFactory userControl1Factory = new FrameworkElementFactory(typeof(UserControl1)); // <local:UserControl
userControl1Factory.SetValue(UserControl1.WidthProperty, 2.0); // Width="2" />
borderFactory.AppendChild(userControl1Factory);
ControlTemplate customControl1Template = new ControlTemplate(typeof(CustomControl1));
customControl1Template.VisualTree = borderFactory;
//...
可以看到,当你写<local:UserControl1 Width="2"/>的时候,属性并不是直接设置到UserControl1上的,而是设置到一个FrameworkElementFactory的工厂上。
当WPF运行中对控件施用模板时,工厂再
1、创建具体的控件实例
2、并把工厂中的模板属性值,应用到实例去。
这里说的应用模板属性,就会有优先级的考虑,很可能这种模板属性的优先级比‘本地值’低(在构造函数里直接设置的算本地值)。
这个可以解释为什么,在构造函数中设置的宽度高度(本地值),不会被模板中的数值覆盖。
相反,如果在StackPanel中直接实例化UserControl1,并设置宽度。那么该设置是‘本地值’,可以生效。
<Window x:Class="WPF3.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WPF3"
Title="MainWindow" Height="350" Width="525">
<Grid>
<StackPanel>
<local:CustomControl1/>
<local:UserControl1 Width="2"/>
</StackPanel>
</Grid>
</Window>
同样是在XMAL中设置UserControl1的Width为2,这个就有效,而在CustomControl1的XAML中设置UserControl1的Width为2就没有效果,这是为什么呢?
<Window x:Class="WPF3.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WPF3"
Title="MainWindow" Height="350" Width="525">
<Grid>
<local:UserControl1 Width="2"/>
</Grid>
</Window>
那为什么,在主窗体中设置的UserControl1的Width值又有效呢?