Как нарисовать векторную графику внутри каждого WPF ListBoxItem во время выполнения? - PullRequest
2 голосов
/ 07 апреля 2011

Я хотел бы нарисовать векторную графику в WPF ListBoxItem.2D-формы очень просты, например, линия или квадрат / прямоугольник.Но ни формы, ни цвета не известны во время компиляции, поэтому это не может быть изображение.

Пример снимка экрана: http://i.stack.imgur.com/EisIQ.jpg (Мой скудный представитель не позволяет мне публиковать изображения в строке ...)

Я полагаю, что это возможно с WPF?Если да, то как, возможно, с использованием элементов Canvas и Rectangle?

Заранее большое спасибо!

EDIT

Я был сбит с толку, казалось, только находя различныепримеры добавления изображений в ListBoxItems, так что я на самом деле не копался. Спасибо за приведенный ниже ответ, который позволил мне встать на ноги.

XAML с использованием двух DataTemplates и объявление селектора шаблона, который выбираетправильный шаблон на основе данных.Цвет также привязан к данным (свойство, называемое 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>

Ответы [ 2 ]

2 голосов
/ 07 апреля 2011

Первое, что нужно определить, это то, где хранятся знания о том, что следует рисовать.

Если все возможные рисунки могут быть нарисованы заранее, вы помещаете их в шаблоны данных и привязываете к отображаемым данным такие вещи, как цвета, кисти и размеры.

Затем используйте селектор шаблона элемента, чтобы выбрать правильную табличку с данными на основе данных.

Если чертежи поступают из базы данных, вам может потребоваться загрузить их как ресурсы и связать изображение в шаблоне данных с битовой картой загрузки.

В общем, попробуйте использовать шаблоны и привязки, прежде чем идти по пути кода C #, потому что такой код гораздо сложнее поддерживать, чем шаблон данных.

0 голосов
/ 11 апреля 2011

Вы можете использовать DataTemplate s на основе типов или 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>
...