解决方案 »
- 求帮助!!!
- 如何利用BHO作出这样的效果
- c# 怎么获取其它程序内的SysListView32可见项
- 一个是没用多线程,另一个用了。问题是:同样的代码,为什么多线程中的某几个效率比单线程得还要高?
- 求一个SQL或算法语句.
- 线程如何调用带返回参数的方法,并返回值
- ###哪位大侠来帮我看看关于网址传汉字的问题!!!
- HID复合设备在HID类的枚举过程中出现的疑问?
- 菜单栏如何设置快捷键,看帖不灵,求指导。
- 请教C#监测系统中任何文件名更改的方法
- System.Net.Sockets.SocketException: 由于系统缓冲区空间不足或队列已满,不能执行套接字上的操作。
- sql server2005 怎么远程连接到 服务器的数据
没有了Name,程序找不到对像了。
但是,控件本身具有特定的逻辑和作用,比如一个按钮,应该是可以点击的;一个颜色选择控件,应该是可以用来选颜色的。
这里就存在了一个矛盾:如果可以任意改变控件的具体表现,那么如何保证它特有的逻辑和作用呢?答案就是WPF控件的‘部件’概念。简单的说,就是你可以任意改变我,但是要提供我期待的部件,否则我的逻辑和作用就不能得到保证。如果阅读TextBoxBase的MSDN参考(TextBox继承于TextBoxBase),你会看到如下的特性:
该特性表明TextBoxBase控件期待你提供一个名字叫PART_ContentHost的部件,该部件必须是FrameworkElement。而TextBoxBase将会把具体的TextView和TextEditor放到PART_ContentHost里面。
2、把CustomControl1(包括文件等)换名为MyUpDown。
3、把Generic.xaml和MyUpDown.cs内容换成:<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MyUpDown">
<Style TargetType="{x:Type local:MyUpDown}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:MyUpDown">
<StackPanel Margin="3" Orientation="Horizontal" Background="{TemplateBinding Background}">
<TextBlock Width="30" VerticalAlignment="Center"
Text="{Binding Path=Value, RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type local:MyUpDown}}}" />
<RepeatButton Width="40" Content="Up" Name="PART_UpButton" />
<RepeatButton Width="40" Content="Down" Name="PART_DownButton" />
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>[TemplatePart(Name = "PART_UpButton", Type = typeof(ButtonBase))]
[TemplatePart(Name = "PART_DownButton", Type = typeof(ButtonBase))]
public partial class MyUpDown : Control
{
static MyUpDown()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(MyUpDown), new FrameworkPropertyMetadata(typeof(MyUpDown)));
} public override void OnApplyTemplate()
{
UpButton = GetTemplateChild("PART_UpButton") as ButtonBase;
DownButton = GetTemplateChild("PART_DownButton") as ButtonBase;
} ButtonBase upButton;
ButtonBase UpButton
{
get { return this.upButton; }
set
{
if (this.upButton != null) this.upButton.Click -= Button_Click;
this.upButton = value;
if (this.upButton != null) this.upButton.Click += Button_Click;
}
} ButtonBase downButton;
ButtonBase DownButton
{
get { return this.downButton; }
set
{
if (this.downButton != null) this.downButton.Click -= Button_Click;
this.downButton = value;
if (this.downButton != null) this.downButton.Click += Button_Click;
}
} void Button_Click(object sender, RoutedEventArgs e)
{
if (object.ReferenceEquals(sender, this.upButton)) this.Value++;
if (object.ReferenceEquals(sender, this.downButton)) this.Value--;
} public int Value
{
get { return (int)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
} public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(int), typeof(MyUpDown));
}4、确保编译成功(控件本身不能运行)。
5、新建一个WPF窗口项目,并添加对MyUpDown项目的引用。
6、从工具栏中,拖一个MyUpDown控件到窗口中,编译运行就可以看到一个类似NumericUpDown的控件。点击Up和Down按钮,可以看到数字的相应变化。下面,我们来自定义(假设是别人提供的)MyUpDown控件:
<Grid>
<MyUpDown:MyUpDown Value="123" >
<MyUpDown:MyUpDown.Template>
<ControlTemplate TargetType="MyUpDown:MyUpDown">
<Grid>
<TextBox Text="{Binding Path=Value,RelativeSource={RelativeSource AncestorType=MyUpDown:MyUpDown}}" Width="150" Height="30" />
<Button Content="UpOnly" Width="50" Height="30" Margin="200 0 0 0" />
</Grid>
</ControlTemplate>
</MyUpDown:MyUpDown.Template>
</MyUpDown:MyUpDown>
</Grid>
在新的模板中,我们用TextBox来支持直接编辑,同时提供一个按键。编译运行,可以发现MyUpDown可以显示Value的数值,但是,两个按钮不见了,我们提供的UpOnly按钮不起作用。这就是我们没有按照控件期待提供特定名字按钮的结果。现在,把Button的代码更改为:
<Button Content="UpOnly" Width="50" Height="30" Margin="200 0 0 0" Name="PART_UpButton" />
编译运行,可以发现只有一个按钮,但该UpOnly按钮可以向上调整数字了。用代码上看,MyUpDown.cs第10行中,当开始应用模板OnApplyTemplate的时候,MyUpDown控件尝试着寻找两个特定名字类型为按钮的部件:
GetTemplateChild("PART_UpButton") as ButtonBase;
...
如果找到按钮部件,则为按钮添加单击事件的响应函数,并在响应函数中相应地对当前数字进行加一或减一,从而达到用按钮调整数字的特定作用(NumericalUpDown)。如果找不到部件,WPF控件可以根据严重程度,选择抛出异常,或减少功能等措施。