【问题标题】:How to draw a vector graphic within each WPF ListBoxItem at run-time?如何在运行时在每个 WPF ListBoxItem 中绘制矢量图形?
【发布时间】:2011-04-07 17:35:43
【问题描述】:

我想在 WPF ListBoxItem 中绘制一个基于矢量的图形。 2D 形状非常简单,例如线条或正方形/矩形。但是在编译时形状和颜色都不知道,所以它不能是图像。

示例屏幕截图:http://i.stack.imgur.com/EisIQ.jpg(我的微薄代表阻止我将图片内嵌发布...)

我相信 WPF 应该可以做到这一点?如果是怎么做,可能涉及 Canvas 和 Rectangle 元素?

提前非常感谢!

编辑

我似乎只发现了向 ListBoxItems 添加图像的各种示例,所以我并没有真正深入研究。感谢下面的答案让我站稳了脚跟。

XAML 使用两个 DataTemplate 和一个模板选择器声明,该选择器根据数据选择正确的模板。颜色也与数据绑定(一个名为 LayerColor 的属性)

<UserControl.Resources>
    <!-- to convert the color -->
    <src:ColorBrushConverter x:Key="colorConverter"/>
    <!-- to select the correct template based on geom type -->
    <src:LayerListDataTemplateSelector x:Key="layerDataTemplateSelector"/>
    <DataTemplate x:Key="lineLayerTemplate">
        <Border BorderThickness="0" BorderBrush="Gray"
               Padding="5" Name="border" Margin="1" >
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition/>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="50"/>
                    <ColumnDefinition />
                </Grid.ColumnDefinitions>

                <Line Margin="5,0,5,0" Height="16"
                 X1="1" Y1="8"
                 X2="35" Y2="8"
                 Stroke="{Binding Path=LayerColor, Converter={StaticResource colorConverter}}"
                 StrokeThickness="2"/>

                <TextBlock Grid.Row="0" Grid.Column="1" Margin="5,0,0,0"
                           Name="layerName" Text="{Binding Path=LayerName}"/>
            </Grid>
        </Border>
    </DataTemplate>
    <DataTemplate x:Key="pointLayerTemplate">
        <Border BorderThickness="0" BorderBrush="Gray"
                Padding="5" Name="border" Margin="1" >
            <Grid>
              <Grid.RowDefinitions>
                <RowDefinition/>
              </Grid.RowDefinitions>
              <Grid.ColumnDefinitions>
                <ColumnDefinition Width="50"/>
                <ColumnDefinition />
              </Grid.ColumnDefinitions>

              <Polygon Grid.Row="0" Grid.Column="0" Margin="5,0,10,0"
                         Fill="{Binding Path=LayerColor, Converter={StaticResource colorConverter}}" 
                         Stroke="Black" StrokeThickness="1"
                         StrokeLineJoin="Round" Width="16" Height="16"
                         Stretch="Fill"
                         Points="8,1 1,8 8,15 15,8 8,1"
                         Visibility="Visible"  Name="diamond"/>

               <TextBlock Grid.Row="0" Grid.Column="1" Margin="5,0,0,0"
                           Name="layerName" Text="{Binding Path=LayerName}"/>
            </Grid>
        </Border>    
    </DataTemplate>
</UserControl.Resources>
<Grid>
    <ListBox x:Name="layerListBox" HorizontalContentAlignment="Stretch" HorizontalAlignment="Stretch"
             ItemTemplateSelector="{StaticResource layerDataTemplateSelector}">
    </ListBox>
</Grid>

【问题讨论】:

  • 您在哪个部分遇到了问题?你试过什么?
  • 根据我的编辑,没有尝试太多。但我想我现在在那里。谢谢!

标签: wpf vector-graphics listboxitem


【解决方案1】:

首先要确定的是关于应该绘制什么的知识位于何处。

如果所有可能的图纸都可以预先绘制,则将它们放入数据模板中,并将颜色、画笔和大小等内容绑定到正在显示的数据中。

然后使用项目模板选择器根据数据选择正确的数据模板。

如果图纸来自数据库,您可能需要将它们作为资源加载并将数据模板中的图像绑定到加载位图。

总而言之,在使用 C# 代码之前尝试使用模板和绑定,因为这样的代码比数据模板更难维护。

【讨论】:

    【解决方案2】:

    您可以基于类型使用DataTemplates,也可以基于模型上的某些属性使用DataTemplateSelector。下面是一个粗略的例子,使用数据的类型来确定在数据旁边绘制什么。

    <ListBox>
      <ListBox.Resources>
        <DataTemplate DataType="{x:Type sys:Int32}">
          <StackPanel Orientation="Horizontal">
            <Rectangle Fill="Blue" Height="5" Width="5"/>
            <TextBlock Text="{Binding}" Margin="4,0,0,0"/>
          </StackPanel>
        </DataTemplate>
        <DataTemplate DataType="{x:Type sys:String}">
          <StackPanel Orientation="Horizontal">
            <Rectangle Fill="Cyan" Height="2" Width="6"/>
            <TextBlock Text="{Binding}" Margin="4,0,0,0"/>
          </StackPanel>
        </DataTemplate>
      </ListBox.Resources>
      <sys:Int32>1</sys:Int32>
      <sys:String>testing testing 1 2 3</sys:String>
    </ListBox>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-15
      • 2010-12-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多