Inherting和自定义WPF控件

时间:2015-05-15 10:13:25

标签: c# .net wpf xaml

我们正在开发一款软件,既可以作为独立软件,也可以作为不同CAD程序的插件。请注意,这是软件的离散版本。不是一个单片版本,它既可以作为插件,也可以作为独立版本。为此,我们正在使用WPF开发一个接口。根据上下文(即它是独立版本还是连接到CAD程序),我希望能够改变外观,最重要的是改变界面的行为。我宁愿不必重写整个界面。

我将简要介绍一下我失败的想法,因为我希望它能为我想要实现的目标提供一些额外的背景。我最初的想法是通过创建必要的控件并将它们组装到页面或窗口中的接口来创建定义默认界面的项目。如果我想要自定义用于特定CAD程序的界面,我将继承控件和页面,并覆盖我想为给定上下文自定义的部分。但是我发现从WPF控件继承不是直截了当的。

快速模拟我尝试的设置概述了here

默认视图包含在页面中收集的名为DefaultUI的基本界面。目前它只包含一个包含在scrollviewer中的自定义画布(称为DefaultCanvas)类型。 DefaultUI的XAML代码是。

<Page x:Class="DefaultView.DefaultUI"
      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:DefaultView"
      mc:Ignorable="d" 
      d:DesignHeight="300" d:DesignWidth="300"
    Title="DefaultUI">

    <Grid>
        <ScrollViewer HorizontalScrollBarVisibility="Auto">
            <local:DefaultCanvas x:Name="mCanvas" 
                         HorizontalAlignment="Stretch" 
                         VerticalAlignment="Stretch" Background="Transparent"
                         AllowDrop="True" IsHitTestVisible="True">
            </local:DefaultCanvas>
        </ScrollViewer>
    </Grid>
</Page>

我在CADView和StandAlone项目中尝试的是从DefaultCanvas和DefaultUI创建CADViewCanvas和CADViewUI等派生类,并能够自定义这些类的行为。实际上我主要想自定义画布的行为,但CADViewUI需要使用派生类而不是DefaultCanvas。我也想从DefaultUI派生的原因是它可能包含几个控件,我只想自定义一个。我在这里意识到我可能有错误的想法,因为我认为当CADViewUI调用它的基本构造函数时,mCanvas将被初始化为DefaultCanvas的一个实例。

CADViewCanvas中所需的附加功能是连接到相关CAD软件的逻辑。在CADView中包含一组包装器。每个包装器将我们模型中的对象连接到CAD软件中的对象。因此,CADViewCanvas应该使用此包装器,而不是直接在模型对象上。对模型对象采取相同的操作,但还需要额外的逻辑来使CAD对象保持最新。

1 个答案:

答案 0 :(得分:0)

当您想要在派生类中调整子控件时,包含子控件的控件的继承可能非常困难。

我建议只在基类中拥有可以通过样式自定义的控件。在派生类中为子控件应用不同的样式是“简单”和干净的:只需定义一个新样式(可以基于默认样式)

当您需要不同的控件行为时,您需要以某种方式提供该行为:

  1. 将所有可能的行为放在基类中并添加属性以打开和关闭它们,以便可以在样式中设置它们。这需要您提前了解需要的内容并创建膨胀控件。我建议不要这样做。
  2. 或实施不同的控制。这意味着您无法将这些添加到基本控件,您必须将它们添加到派生控件。我认为更清洁。
  3. 简而言之:对于所有派生类来说不相同的功能不属于基类,所以不要把它放在那里。如果它很简单,布局/颜色/可见性等视觉效果可能是一种合适的解决方案。