依赖属性与路由事件详解
立即解锁
发布时间: 2025-08-26 01:40:45 阅读量: 17 订阅数: 27 AIGC 

### 依赖属性与路由事件详解
#### 依赖属性
在开发中,依赖属性是一个重要的概念。`RegisterAttached()` 方法的参数与 `Register()` 方法完全相同。创建附加属性时,无需定义 .NET 属性包装器,因为附加属性可以设置在任何依赖对象上。例如,`Grid.Row` 属性可以设置在 `Grid` 对象上(如果有嵌套的 `Grid`),甚至可以设置在不在 `Grid` 中的元素上,即使元素树中没有 `Grid` 对象。
附加属性需要一对静态方法来设置和获取属性值,这些方法使用从 `DependencyObject` 类继承的 `SetValue()` 和 `GetValue()` 方法。静态方法应命名为 `SetPropertyName()` 和 `GetPropertyName()`。以下是 `Grid.Row` 属性的设置和获取方法示例:
```csharp
public static void SetRow(UIElement element, int value)
{
element.SetValue(Grid.RowProperty, value);
}
public static int GetRow(UIElement element)
{
return (int)element.GetValue(Grid.RowProperty);
}
```
使用代码将元素放置在 `Grid` 的第一行的示例如下:
```csharp
Grid.SetRow(txtElement, 0);
```
##### WrapBreakPanel 示例
为了更好地理解依赖属性,我们来看一个 `WrapBreakPanel` 的示例。`WrapBreakPanel` 通常表现得像 `WrapPanel`,但它有一个新特性:可以通过附加属性在任意位置强制换行。
首先,为 `WrapBreakPanel` 定义一个 `Orientation` 属性:
```csharp
public static readonly DependencyProperty OrientationProperty =
DependencyProperty.Register("Orientation", typeof(Orientation),
typeof(WrapBreakPanel), new PropertyMetadata(Orientation.Horizontal));
public Orientation Orientation
{
get
{
return (Orientation)GetValue(OrientationProperty);
}
set
{
SetValue(OrientationProperty, value);
}
}
```
在 Silverlight 页面中使用 `WrapBreakPanel` 时,可以像设置其他属性一样设置 `Orientation` 属性:
```xml
<local:WrapBreakPanel Margin="5" Orientation="Vertical">
...
</local:WrapBreakPanel>
```
`WrapBreakPanel` 还包含一个附加属性 `LineBreakBefore`,允许子元素强制换行。定义如下:
```csharp
public static DependencyProperty LineBreakBeforeProperty =
DependencyProperty.RegisterAttached("LineBreakBefore", typeof(bool),
typeof(WrapBreakPanel), null);
public static bool GetLineBreakBefore(UIElement element)
{
return (bool)element.GetValue(LineBreakBeforeProperty);
}
public static void SetLineBreakBefore(UIElement element, bool value)
{
element.SetValue(LineBreakBeforeProperty, value);
}
```
修改 `MeasureOverride()` 和 `ArrangeOverride()` 方法来检查强制换行:
```csharp
// Check if the element fits in the line, or if a line break was requested.
if ((currentLineSize.Width + desiredSize.Width > constraint.Width) ||
(WrapBreakPanel.GetLineBreakBefore(element)))
{ ... }
```
在 XAML 中使用 `LineBreakBefore` 属性的示例如下:
```xml
<local:WrapBreakPanel Margin="5" Background="LawnGreen">
<Button Width="50" Content="Button"></Button>
<Button Width="150" Content="Wide Button"></Button>
<Button Width="50" Content="Button"></Button>
<Button Width="150" Content="Button with a Break"
local:WrapBreakPanel.LineBreakBefore="True" FontWeight="Bold"></Button>
<Button Width="150" Content="Wide Button"></Button>
<Button Width="50" Content="Button"></Button>
</local:WrapBreakPanel>
```
#### 路由事件
每个 .NET 开发人员都熟悉事件的概念,WPF 通过事件路由的新概念增强了 .NET 事件模型,Silverlight 借鉴了 WPF 的部分路由事件模型,但进行了简化。Silverlight 只支持冒泡事件,即事
0
0
复制全文
相关推荐









