【发布时间】:2017-02-09 16:05:22
【问题描述】:
我可以用 VB 或 C# 来回答,我都知道,但最终的解决方案将用 VB.Net 编写。本质上,我想使用一个模板在 n 次排列中重用基的从属属性,但是我正在使用带有路由后面代码的 xaml 并放弃了样式模板。基本上我想在我想用作基础的用户控件中做这样的事情:
XAML:
<UserControl x:Class="Test"
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:WPFControls"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid Name="PART_TestLayout">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Text="{Binding TestTitle}" Height="30" Background="White" Foreground="Black" />
<TextBlock Name="PART_Text2" Grid.Row="1" Background="White" />
</Grid>
</UserControl>
XAML 背后的代码:
Imports System.ComponentModel
Public Class Test
Public Sub New()
InitializeComponent()
PART_TestLayout.DataContext = Me
End Sub
Public Shared ReadOnly TestTitleProperty As DependencyProperty = DependencyProperty.Register("TestTitle", GetType(String), GetType(Test), New UIPropertyMetadata(String.Empty, AddressOf TestChanged))
Public Property TestTitle As String
Get
Return CType(GetValue(TestTitleProperty), String)
End Get
Set
SetValue(TestTitleProperty, Value)
End Set
End Property
Private Shared Sub TestChanged(d As DependencyObject, e As DependencyPropertyChangedEventArgs)
Dim m = DirectCast(d, Test)
m.PART_Text2.Text = $"Changed {DateTime.Now.ToLongTimeString}"
End Sub
Public MustOverride Sub DoThing()
End Class
我想做的是这样的:
使用1:
<local:Test x:Class="TestInheritance"
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:WPFControls"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Label Content="I am the first implentation"/>
<local:Test TestTitle="{Binding TestText}" />
</Grid>
</local:Test>
使用2
<local:Test x:Class="TestInheritance2"
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:WPFControls"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Label Content="I am the second implentation"/>
<local:Test TestTitle="{Binding TestText}" />
</Grid>
</local:Test>
现在我知道我可以做这样的事情(并且可能是我应该走的路)
<UserControl x:Class="TestInheritance"
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:WPFControls"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<local:Part1 TestTitle="{Binding TestText}" />
<!-- myproprietaryContent -->
<local:Part2 TestLegend="{Binding TestText2}" />
</Grid>
</local:Test>
但我宁愿只从基本模板继承,然后应用我需要的一切。 我是否需要使用样式模板才能做到这一点,或者我可以按原样重用 XAML 用户控件吗? 每次我尝试在后面的代码中执行“继承(基类名)”时,我都会得到这个错误:
'Base class 'Test' specified for class 'TestInheritance' cannot be different from the base class 'UserControl' of one of its other partial types.'
所以我有点摸不着头脑,对 WPF 的语言和功能知之甚少,这是可以做到的,还是应该为此做的。
【问题讨论】:
-
基类不应包含任何内容或 XAML 文件,因为这将被派生的 UserControl 实例覆盖。您希望能够在派生控件中使用“PART_TestLayout”网格吗?
-
是的,大部分绘图是在后面的代码中完成的,但我仍然在传统的 MVVM 架构中绑定数据元素。我想重用常见的 Dependent 属性,而不是如何挑剔。我只是不想为不同的迭代设置 2、3 或 4 次。
-
@mm8 继承自任何东西的 XAML 用户控件必须有更多的继承。每次我尝试时,我总是得到:'为类'Test'指定的基类'BaseTest'不能与其其他部分类型之一的基类'UserControl'不同。'。我可以让它本身继承'UserControl',把这个
-
实际上,我以前的 Visual Studio 2017 RC 看起来像是某种奇怪的随机错误。这就是我尝试使用 RC 编写生产代码的结果。
-
我提供了一个工作示例。希望对您有所帮助。
标签: c# wpf vb.net inheritance