如何扩展WPF Path控件

时间:2014-01-24 19:46:18

标签: c# wpf path shape

在我的Windows窗体应用程序中,它将WPF复合控件作为空调系统的内部显示器。在该图中,每个气体管道和流体管道由路径控制表示。我们希望Path对象的颜色(使用Path.Fill)表示压力警报状态,例如低警报,中警报或高警报。

我们的部分代码列为:

<local:UC_Line_1 Margin="27.728,16.486,39.219,36.308" DataContext="{Binding Pipe1Alert}"/>
<local:UC_Line_2 Margin="21.172,15.322,33.218,6.876"  DataContext="{Binding Pipe2Alert}"/>
<local:UC_Line_3 Margin="46.907,0,31.36,26.178" DataContext="{Binding Pipe3Alert}"/>
<local:UC_Line_4 Margin="0,11.939,20.842,13.835" DataContext="{Binding Pipe4Alert}"/>

每个UC_Line_x控件都具有类似的代码:

<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:enum="clr-namespace:KPRC.App.AC.Enums"
x:Class="KPRC.App.AC.UC_Line_2"
x:Name="Line_2">
 <UserControl.Resources>
    <!-- Colors -->
    <!--Red Fill Color-->
    <SolidColorBrush x:Key="RedFill" Color="Red"/>
    <!--Yellow Fill Color-->
    <SolidColorBrush x:Key="YellowFill" Color="Yellow"/>
    <!--Orange Fill Color-->
    <SolidColorBrush x:Key="OrangeFill" Color="Orange"/>
</UserControl.Resources>

<Grid x:Name="UC_Line_2_LayoutRoot">
    <Path x:Name="FL_2" Stretch="Fill" Data="M20.167,0 L24.167,0 24.167,28.924 44,28.924 44,32.924 24.167,32.924 20.167,32.924 0,32.924 0,28.924 20.167,28.924 z">
        <Path.Style>
            <Style>
                <Style.Triggers>
                    <!-- High Alert -->
                    <DataTrigger Binding="{Binding AlertState}">
                        <DataTrigger.Value>
                            <enum:AlertState>High</enum:AlertState>
                        </DataTrigger.Value>
                        <Setter Property="Path.Fill" Value="{StaticResource RedFill}"/>
                    </DataTrigger>
                    <!-- Medium Alert -->
                    <DataTrigger Binding="{Binding AlertState}">
                        <DataTrigger.Value>
                            <enum:AlertState>Medium</enum:AlertState>
                        </DataTrigger.Value>
                        <Setter Property="Path.Fill" Value="{StaticResource OrangeFill}"/>
                    </DataTrigger>
                    <!-- Low Alert -->
                    <DataTrigger Binding="{Binding AlertState}">
                        <DataTrigger.Value>
                            <enum:AlertState>Low</enum:AlertState>
                        </DataTrigger.Value>
                        <Setter Property="Path.Fill" Value="{StaticResource YellowFill}"/>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </Path.Style>
    </Path>
</Grid>

除了路径几何上的差异外,每个UC_Line_x控件的代码几乎完全相同。 我知道这是一个巨大的代码重复。

我正在考虑替代方法来支持相同的结果。由于每个管道仅在路径几何中有所不同,因此可以使用基于System.Windows.Form.Path的UC_Line_Path控件以及额外的“AlertState”属性,以在复合UI中包含以下代码:

<local:UC_Line_Path AlertState="{Binding Pipe1Alert.AlertState}" Data="M20.167,0 L24.167,0 24.167,28.924 44,28.924 44,32.924 24.167,32.924 20.167z"/>
<local:UC_Line_Path AlertState="{Binding Pipe2Alert.AlertState}" Data="M20.167,0 L24.167,0 24.167,28.924 44,28.924 44,32.924 28.924 z"/>
<local:UC_Line_Path AlertState="{Binding Pipe3Alert.AlertState}" Data="M20.167,0 L24.167,0 24.167,28.924 44,28.924 44,32.924 24.167,32.924 20.167,32.924 0,32.924 0,28.924 z"/>
<local:UC_Line_Path AlertState="{Binding Pipe4Alert.AlertState}" Data="M20.167,0 L24.167,0 24.167,28.924  20.167,32.924 0,32.924 0,28.924 20.167,28.924 z"/>

这种方法的问题是 1. Path是一个密封的类。 WPF不允许我延长它。 2.即使假设我可以从Path控件扩展,如何添加一个新属性“AlertState”以与原始UC_Line_1代码中显示的数据触发器一起使用?

谢谢和问候。

1 个答案:

答案 0 :(得分:1)

这是一个直截了当的解决方案。使用单个控件UC_Line,并向其添加属性PathData。然后,您可以从控件中绑定到该属性:

<Path x:Name="FL_2" Stretch="Fill" 
    Data="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=PathData}">

然后使用实例提供PathData:

<local:UC_Line Margin="27.728,16.486,39.219,36.308" 
               DataContext="{Binding Pipe1Alert}"
               PathData="M20.167,0 L24.167,0 24.167,28.924 44,28.924 44,32.924 24.167,32.924 20.167,32.924 0,32.924 0,28.924 20.167,28.924 z"
/>

请注意,该属性应为dependency property类型的Geometry

public class UC_Line : UserControl
{
    public static readonly DependencyProperty PathDataProperty =
        DependencyProperty.Register("PathData", typeof(Geometry), typeof(UC_Line), null);
    public Geometry PathData
    {
        get { return (Geometry)GetValue(PathDataProperty); }
        set { SetValue(PathDataProperty, value); }
    }

    // ... etc
}