GoXam - 数据绑定与模板

GoXam 是第一个从头开始设计为 Windows Presentation Foundation (WPF) 中使用的 Microsoft XAML 语言的自然扩展的图表控件。 此环境必不可少的是数据绑定和数据模板。 GoXam 将这些概念清晰连贯地集成到 XAML 的强大图表扩展中。

图表模型和数据绑定

XAML 定义的表示的主要特征之一是使用数据绑定。 然而,图表控件必须支持比典型控件更复杂的功能。

图表至少可以支持数据项之间的两种关系:

  • 形成节点和链接图的关系(或类似术语:节点和弧,或实体和关系,或顶点和边)
  • 分组关系,其中一个组包含成员; 可能用于部分/子部分包含,或用于子图的嵌套

GoXam 利用模型来发现、维护、导航和修改基于图表绑定的数据的这些关系。 并非图表背后的所有数据都具有相同的复杂性,因此我们提供了三个主要模型类,为您提供易用性、性能和功能的正确组合。

TreeModel 是最简单的模型。 它适用于数据形成树结构图的应用程序。

当每个节点都有一个连接到该节点或从该节点连接的节点列表时,将使用 GraphModel。 GraphModel 还支持简单的分组。

第三个模型是 GraphLinksModel,其中您的数据包括节点的源以及连接它们的链接的源。 GraphLinksModel 还支持链接信息,允许每个节点上有不同的链接连接点。 它还支持链接上的标签。

一旦创建了模型,并且模型的数据被初始化并分配给图表,您就在模型和图表之间创建了自动链接。 对模型的更改会更新图表,对图表的更改(通常由用户)会更新模型。

如果您查看我们的演示,您会惊讶于只需编写如此少的代码即可可视化和更新数据。

节点数据模板

任何节点或链接的外观不仅取决于它所绑定的数据,还取决于用于定义其可视树元素的 DataTemplate。 数据模板是可重用的 XAML 片段,它定义了如何显示绑定的数据。 因此,图表的外观与代码是分开的。 只需编辑定义节点或链接的 XAML 即可更改图表的外观。

由于节点和链接是由 XAML 定义的,因此很容易将 WPF 图形(矩形、文本、路径、渐变、图像甚至视频)的所有功能合并到您的图表中,包括使用动画、故事板和模糊等效果 和投影。

使用这个 NodeTemplate 节点可以很简单

simple GoXam diagram


    <DataTemplate>
      <TextBlock Text="{Binding Path=Data}" />
    </DataTemplate>
    

但也可以根据您的需要定义复杂的节点(单击图像查看 XAML)

Click to Show DataTemplate XAML code
Click to Show DataTemplate XAML code
Click to Show DataTemplate XAML code
紫色节点 Alpha 的数据模板:

      <DataTemplate x:Key="NodeTemplate4">
        <!-- a NodePanel shows a background shape and places the other panel children inside the shape -->
        <go:NodePanel go:Node.SelectionAdorned="True"
                      go:Node.ToSpot="LeftSide" go:Node.FromSpot="RightSide" >
          <go:NodeShape go:NodePanel.Figure="Database" Stroke="Black" StrokeThickness="1">
            <Shape.Fill>
              <!-- use a fancier brush than a simple solid color -->
              <LinearGradientBrush StartPoint="0.0 0.0" EndPoint="1.0 0.0">
                <LinearGradientBrush.GradientStops>
                  <GradientStop Color="{Binding Path=Data.Color,
                          Converter={StaticResource theStringColorConverter}}" Offset="0.0" />
                  <GradientStop Color="White" Offset="0.5" />
                  <GradientStop Color="{Binding Path=Data.Color,
                          Converter={StaticResource theStringColorConverter}}" Offset="1.0" />
                </LinearGradientBrush.GradientStops>
              </LinearGradientBrush>
            </Shape.Fill>
          </go:NodeShape>
          <!-- this TextBlock element is arranged inside the NodePanel’s shape -->
          <TextBlock Text="{Binding Path=Data.Key}" TextAlignment="Center"
                     HorizontalAlignment="Center" VerticalAlignment="Center" />
        </go:NodePanel>
      </DataTemplate>
      
浅蓝色 OrgChart 节点的 DataTemplate:


    <DataTemplate x:Key="NodeTemplate" >
      <go:NodePanel go:Node.SelectionAdorned="True" >
        <Border Background="Azure" BorderBrush="Black" BorderThickness="1" MaxWidth="200" >
          <Grid MaxWidth="200">
            <Grid.RowDefinitions>
              <RowDefinition Height="Auto" />
              <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
            <Grid Grid.Row="0" >
              <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="Auto" />
              </Grid.ColumnDefinitions>
              <TextBlock Grid.Column="0" Text="{Binding Path=Data.Name}" FontWeight="Bold"
                         TextAlignment="Left" TextWrapping="Wrap" Margin="4 4 4 2" />
              <Border Grid.Column="1" BorderBrush="Black" BorderThickness="2"
                      Height="34" Margin="2"
                      Width="{Binding Path=Data.Flag,
                              Converter={StaticResource theImageSizeConverter}}">
                <Image Stretch="Fill" Source="{Binding Path=Data.Flag}" />
              </Border>
            </Grid>
            <TextBlock Grid.Row="1" Text="{Binding Path=Data.PersonData}"
                       TextAlignment="Left" TextWrapping="Wrap" Margin="4 4 4 2" />
          </Grid>
        </Border>
      </go:NodePanel>
    </DataTemplate>
  
实体关系节点的数据模板:

  <DataTemplate x:Key="NodeTemplate">
    <Border Background="Gray" BorderBrush="Gray" BorderThickness="2" CornerRadius="3"
            go:Part.SelectionAdorned="True" go:Part.Resizable="True"
            go:Node.FromSpot="AllSides" go:Node.ToSpot="AllSides"
            go:Node.Location="{Binding Path=Data.Location, Mode=TwoWay}">
      <Grid>
        <Grid.RowDefinitions>
          <RowDefinition Height="Auto" />
          <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <Grid Grid.Row="0">
          <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="Auto" />
          </Grid.ColumnDefinitions>
          <TextBlock Grid.Column="0" HorizontalAlignment="Center"
                     Text="{Binding Path=Data.Key}" FontWeight="Bold" />
          <Button Grid.Column="1" Content="*" Click="Button_Click" />
        </Grid>
        <ListView Grid.Row="1" Background="White" HorizontalAlignment="Stretch"
                  ItemsSource="{Binding Path=Data.Items}">
          <ListView.View>
            <GridView>
              <GridView.Columns>
                <GridViewColumn>
                  <GridViewColumn.CellTemplate>
                    <DataTemplate>
                      <go:NodeShape
                          go:NodePanel.Figure="{Binding Path=Figure}"
                          Width="10" Height="10"
                          Fill="{Binding Path=Color,
                                 Converter={StaticResource theStringBrushConverter}}"
                          Stroke="Black" StrokeThickness="1" />
                    </DataTemplate>
                  </GridViewColumn.CellTemplate>
                </GridViewColumn>
                <GridViewColumn Header="Name"
                                DisplayMemberBinding="{Binding Path=Name}" />
              </GridView.Columns>
            </GridView>
          </ListView.View>
        </ListView>
      </Grid>
    </Border>
  </DataTemplate>
  

链接的数据模板

GoXam 还支持链接的 DataTemplate,以及正交、贝塞尔、圆角、跳转和避免节点路由等链接功能。 (点击图片查看 XAML)

Click to Show DataTemplate XAML code

普通路由

Click to Show DataTemplate XAML code

正交

Click to Show DataTemplate XAML code

贝塞尔

Click to Show DataTemplate XAML code

有曲线

Click to Show DataTemplate XAML code

圆角

带有箭头的简单链接的数据模板

    <DataTemplate x:Key="LinkTemplate2">
      <go:LinkPanel go:Part.SelectionElementName="Path"
                    go:Part.SelectionAdorned="True" >
        <go:LinkShape x:Name="Path" go:LinkPanel.IsLinkShape="True"
                      Stroke="Black" StrokeThickness="1" />
        <!-- the arrowhead -->
        <Polygon Fill="Black" Points="8 4  0 8  2 4  0 0"
                 go:LinkPanel.Alignment="1 0.5" go:LinkPanel.Index="-1"
                 go:LinkPanel.Orientation="Along" />
      </go:LinkPanel>
    </DataTemplate>
    
带有箭头的正交链接的数据模板

  <DataTemplate x:Key="LinkTemplate4">
    <go:LinkPanel go:Part.SelectionElementName="Path"
                  go:Part.SelectionAdorned="True">
      <go:Link.Route>
        <go:Route Routing="Orthogonal" />
      </go:Link.Route>
      <go:LinkShape x:Name="Path" go:LinkPanel.IsLinkShape="True"
                    Stroke="Black" StrokeThickness="1" />
      <Polygon Fill="Black" Points="8 4  0 8  2 4  0 0"
               go:LinkPanel.Alignment="1 0.5" go:LinkPanel.Index="-1"
               go:LinkPanel.Orientation="Along" />
    </go:LinkPanel>
  </DataTemplate>
  
启用贝塞尔曲线的选项。 您可以通过设置 Route.Curviness 属性来控制曲率。 由于同一对节点之间的链接数量不同,它会自动计算 Curviness 的值,除非您明确指定它。

    <go:Link.Route>
      <go:Route Curve="Bezier" />
    </go:Link.Route>
    

Click to Show DataTemplate XAML code

使用避免节点

Click to Show DataTemplate XAML code

用 Jumpovers 四舍五入

启用 避免节点 链接路由的选项

    <go:Link.Route>
      <go:Route Routing="AvoidsNodes" />
    </go:Link.Route>
    
带圆角的正交布线

    <go:Link.Route>
      <go:Route Routing="Orthogonal" Curve="JumpOver" Corner="10" />
    </go:Link.Route>
    

带注释的链接

向链接添加注释或装饰是很常见的,尤其是文本。 您可以轻松地将所需的任何元素添加到 LinkPanel。 (点击图片查看 XAML)

Links with labels

链接支持标签

that follow the path of the link

遵循链接的路径

在链接的发件人和收件人两端贴上标签

      <DataTemplate x:Key="LinkTemplate5">
        <go:LinkPanel>
          <go:LinkShape Stroke="Black" StrokeThickness="1" />
          <Polygon Fill="Black" Points="8 4  0 8  2 4  0 0" go:LinkPanel.Index="-1"
                   go:LinkPanel.Alignment="1 0.5" go:LinkPanel.Orientation="Along" />
          <TextBlock Text="From" go:LinkPanel.Index="0"
                   go:LinkPanel.Offset="NaN NaN" go:LinkPanel.Orientation="Upright" />
          <TextBlock Text="To" go:LinkPanel.Index="-1"
                   go:LinkPanel.Offset="NaN NaN" go:LinkPanel.Orientation="Upright" />
        </go:LinkPanel>
      </DataTemplate>
      

even curvy paths

甚至弯曲的路径

link labels can be any element

链接标签可以是任何元素

链接标签可以是任何元素 - 这里使用红色 8 角星和 XAML 按钮控件

      <go:NodePanel go:LinkPanel.Index="0" go:LinkPanel.Offset="5 5" >
        <Path go:NodePanel.Figure="EightPointedStar" Fill="Red"
              Width="10" Height="10" />
      </go:NodePanel>
      <Button Content="?" Click="Button_Click" />

      <!-- LinkPanel labels in WPF -->
      <go:NodeShape go:LinkPanel.Index="0" go:LinkPanel.Offset="5 5"
                    go:NodePanel.Figure="EightPointedStar" Fill="Red"
                    Width="10" Height="10" />
      <Button Content="?" Click="Button_Click" />
      

链接连接点

默认情况下,链接将围绕节点的边缘连接。 (点击图片查看 XAML)

links connect to edge of any shape

链接连接到任何形状的边缘

connect to spot

或特定地点

或到一侧或多侧

设置 Node.FromSpot 和 Node.ToSpot 附加属性

      <DataTemplate x:Key="NodeTemplate2">
        <TextBlock Text="{Binding Path=Data.Key}" go:Node.SelectionAdorned="True"
                   go:Node.ToSpot="MiddleLeft" go:Node.FromSpot="MiddleRight" />
      </DataTemplate>
      
您还可以指定链接进入节点不是在单个位置,而是沿一侧展开。 请注意,我们在这里也为节点添加了边框。

      <DataTemplate x:Key="NodeTemplate3">
        <Border BorderBrush="Black" BorderThickness="1" Padding="3"
                go:Node.SelectionAdorned="True"
                go:Node.ToSpot="LeftSide" go:Node.FromSpot="RightSide" >
          <TextBlock Text="{Binding Path=Data.Key}" />
        </Border>
      </DataTemplate>
      

有时您希望有不同的逻辑和图形位置来连接链接。 GoXam 允许您从任何元素创建链接连接点。 链接可能连接到的元素称为端口。 一个节点中可能有任意数量的端口。 (点击图片查看 XAML)

nodes with ports

带端口的节点

nodes with ports

带有输入/输出端口的逻辑图

具有 2 个输入端口和一个输出端口的灰色节点

      <DataTemplate x:Key="NodeTemplate4">
        <Border BorderBrush="Black" BorderThickness="1"
                go:Node.SelectionAdorned="True">
          <Grid Background="LightGray">
            <Grid.ColumnDefinitions>
              <ColumnDefinition Width="Auto" />
              <ColumnDefinition Width="*" />
              <ColumnDefinition Width="Auto" />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
              <RowDefinition Height="Auto" />
              <RowDefinition Height="*" />
              <RowDefinition Height="*" />
            </Grid.RowDefinitions>
            <TextBlock Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="3"
                       Text="{Binding Path=Data.Key}" TextAlignment="Center"
                       FontWeight="Bold" TextWrapping="Wrap" Margin="4,4,4,2" />
            <StackPanel Grid.Column="0" Grid.Row="1" Orientation="Horizontal">
              <!-- this Rectangle is a port, identified with the string "A";
                   links only come into it at the middle of the left side -->
              <Rectangle Width="6" Height="6" Fill="Black"
                         go:Node.PortId="A" go:Node.ToSpot="MiddleLeft" />
              <TextBlock Text="A" />
            </StackPanel>
            <StackPanel Grid.Column="0" Grid.Row="2" Orientation="Horizontal">
              <!-- this Rectangle is another input port, named "B" -->
              <Rectangle Width="6" Height="6" Fill="Black"
                         go:Node.PortId="B" go:Node.ToSpot="MiddleLeft" />
              <TextBlock Text="B" />
            </StackPanel>
            <StackPanel Grid.Column="2" Grid.Row="1" Grid.RowSpan="2"
                        Orientation="Horizontal" VerticalAlignment="Center">
              <TextBlock Text="Out" />
              <!-- this Rectangle is another port, identified with the string "Out";
                   links only go out of it at the middle of the right side -->
              <Rectangle Width="6" Height="6" Fill="Black"
                         go:Node.PortId="Out" go:Node.FromSpot="MiddleRight" />
            </StackPanel>
          </Grid>
        </Border>
      </DataTemplate>
      


京公网安备 11010802039168号    |    备案号:京ICP备09015132号-949