2017-02-09 99 views
0

我会很好的在VB或C#中的答案,我知道两个,最终的解决方案将写在VB.Net虽然。实质上,我想使用一个模板来重复使用n个排列中的基础的从属属性,但是我使用的是代码隐藏在路由后面的xaml,并放弃了一个Style模板。基本上我想要做的用户控件这样的事情我想用一个基地:如何从基本WPF用户控件继承从属属性到继承的新用户控件?

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 

我想做的是这样的:

USE1:

<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> 

USE2

<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 UserControl吗?每当我背后我得到这个错误做“继承(baseclassname)”中的代码:

'Base class 'Test' specified for class 'TestInheritance' cannot be different from the base class 'UserControl' of one of its other partial types.' 

所以,我有种被卡住划伤,不知道够不上语言和WPF的能力,我的头这可以要做,或者应该为此做。

+1

基类不应该有任何内容或XAML文件,因为这将由派生的UserControl实例重写。你想在派生控件中使用“PART_TestLayout”网格吗? – mm8

+0

大多数情况下绘图是在后面的代码中完成的,但我仍然绑定传统MVVM体系结构中的数据元素。我想重复使用通用的依赖属性,而不是如何挑剔。我只是不想为不同的迭代设置2,3或4次。 – djangojazz

+0

@ mm8用XAML用户控件继承任何东西,必须有更多的继承。每次我尝试时,我总是得到:''Test'类指定的基类'BaseTest'不能与其他部分类型的基类'UserControl'不同。'。我可以让它继承'UserControl'本身或不是,把这个 djangojazz

回答

1

不能重用基地UserControl的内容,该内容将被衍生覆盖控制。基类应该只定义依赖项属性并且没有任何XAML标记。

请参考以下示例代码:

Test.vb(基类):

Public MustInherit Class Test 
    Inherits UserControl 

    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) 
     '... 
    End Sub 
    Public MustOverride Sub DoThing() 
End Class 

UserControl1.xaml:

<local:Test x:Class="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" 
      xmlns:local="clr-namespace:WpfApplicationVb1" 
      mc:Ignorable="d" 
      d:DesignHeight="300" d:DesignWidth="300"> 
    <Grid> 

    </Grid> 
</local:Test> 

的UserControl1。 XAML。vb:

Public Class UserControl1 
    Inherits Test 

    Public Overrides Sub DoThing() 
     '... 
    End Sub 
End Class 
+0

这就是我正在寻找的和我最终走的路线。即使只是重复使用我的属性也是一个巨大的胜利。 – djangojazz

0

UserControls是为了组成。如果你想要明智的继承,你应该使用自定义控件。

http://wpftutorial.net/HowToCreateACustomControl.html

在你的情况我会从TextBlock的继承和BottomText依赖属性添加到它。然后在Generic.xaml中进行设计,大部分与您所做的一样。

也看到这里的用户控件和自定义控件之间的差异(后者模式是专为你的使用情况):http://wpftutorial.net/CustomVsUserControl.html

+0

这个问题我很好奇,但是通过这样的路线,你通常在Style中有这样的东西:'