2013-06-27 2 views
0

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

Я не знаю много о WPF, поэтому я нашел некоторый код, который делает изменение размеров форм here

Это изменение размера работы будет, но теперь я застрял, как динамически создать новую версию управления , Я использую ContentControl, который обрабатывает изменение размера, и он имеет внутренний прямоугольник для отображения. XAML выглядит следующим образом:

<Window x:Class="MazeBuilder.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:s="clr-namespace:MazeBuilder" 
    Title="MainWindow" Height="480" Width="640"> 
<Window.Resources> 

    <!-- ResizeDecorator Template --> 
    <ControlTemplate x:Key="ResizeDecoratorTemplate" TargetType="{x:Type Control}"> 
     <Grid> 
      <s:ResizeThumb Height="3" Cursor="SizeNS" Margin="0 -4 0 0" 
        VerticalAlignment="Top" HorizontalAlignment="Stretch"/> 
      <s:ResizeThumb Width="3" Cursor="SizeWE" Margin="-4 0 0 0" 
        VerticalAlignment="Stretch" HorizontalAlignment="Left"/> 
      <s:ResizeThumb Width="3" Cursor="SizeWE" Margin="0 0 -4 0" 
        VerticalAlignment="Stretch" HorizontalAlignment="Right"/> 
      <s:ResizeThumb Height="3" Cursor="SizeNS" Margin="0 0 0 -4" 
        VerticalAlignment="Bottom" HorizontalAlignment="Stretch"/> 
      <s:ResizeThumb Width="7" Height="7" Cursor="SizeNWSE" Margin="-6 -6 0 0" 
        VerticalAlignment="Top" HorizontalAlignment="Left"/> 
      <s:ResizeThumb Width="7" Height="7" Cursor="SizeNESW" Margin="0 -6 -6 0" 
        VerticalAlignment="Top" HorizontalAlignment="Right"/> 
      <s:ResizeThumb Width="7" Height="7" Cursor="SizeNESW" Margin="-6 0 0 -6" 
        VerticalAlignment="Bottom" HorizontalAlignment="Left"/> 
      <s:ResizeThumb Width="7" Height="7" Cursor="SizeNWSE" Margin="0 0 -6 -6" 
        VerticalAlignment="Bottom" HorizontalAlignment="Right"/> 
     </Grid> 
    </ControlTemplate> 

    <!-- Designer Item Template--> 
    <ControlTemplate x:Key="DesignerItemTemplate" TargetType="ContentControl"> 
     <Grid DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}"> 

      <Control Template="{StaticResource ResizeDecoratorTemplate}"/> 
      <ContentPresenter Content="{TemplateBinding ContentControl.Content}"/> 
     </Grid> 
    </ControlTemplate> 

</Window.Resources> 
    <Canvas x:Name="LayoutRoot" MouseDown="LayoutRoot_MouseDown" MouseMove="LayoutRoot_MouseMove"> 
    <Popup Name="PopupEsales" Placement="Right" IsEnabled="True" IsOpen="False" Grid.RowSpan="2"> 
     <ListView Height="145" HorizontalAlignment="Stretch" Margin="0,0,0,0" Name="lvSalesPersonIdSearch" VerticalAlignment="Top" Width="257" > 
      <ListView.View> 
       <GridView> 
        <GridViewColumn Header="Sales Persons Id" Width="100" DisplayMemberBinding="{Binding Path=SPID}" /> 
        <GridViewColumn Header="Name" Width="100" DisplayMemberBinding="{Binding Path=Name}" /> 
       </GridView> 
      </ListView.View> 
     </ListView> 
    </Popup> 
    <Menu Height="23" IsMainMenu="True" HorizontalAlignment="Left" Name="menu1" VerticalAlignment="Top" Width="640"> 
     <MenuItem Header="File"> 
      <MenuItem Header="New Maze" Click="New_Click" /> 
      <MenuItem Header="Load Maze" Click="Load_Click" /> 
      <MenuItem Header="Save Maze" Click="Save_Click" /> 

     </MenuItem> 
     <MenuItem Header="Tools"> 
      <MenuItem Header="Show" Click="ShowTools_Click" /> 
     </MenuItem> 
    </Menu> 

    <ContentControl Width="130" 
       MinWidth="50" 
       Height="130" 
       MinHeight="50" 
       Canvas.Top="150" 
       Canvas.Left="470" 
       Template="{StaticResource DesignerItemTemplate}"> 
     <Rectangle Fill="Blue" 
      IsHitTestVisible="False"/> 
    </ContentControl> 


    <Canvas.Background> 
     <SolidColorBrush Color="White" Opacity="0"/> 
    </Canvas.Background> 


</Canvas> 

управления, который я пытаюсь дублировать динамически этот бит:

  <ContentControl Width="130" 
       MinWidth="50" 
       Height="130" 
       MinHeight="50" 
       Canvas.Top="150" 
       Canvas.Left="470" 
       Template="{StaticResource DesignerItemTemplate}"> 
     <Rectangle Fill="Blue" 
      IsHitTestVisible="False"/> 
    </ContentControl> 

Это шаблон свойство, которое дает мне проблему - как создать его динамически.

То, что я пытался это прочитать в Xaml в A XamlReader, чтобы создать элемент управления, например, так:

private void CopyBlockWithXaml() 
    { 
     StringBuilder sb = new StringBuilder(); 
     sb.Append(@"<ContentControl xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'"); 
     sb.Append(" Width=\"130\" MinWidth=\"50\" Height=\"130\""); 
     sb.Append("  MinHeight=\"50\" "); 
     sb.Append("  Canvas.Top=\"150\""); 
     sb.Append("  Canvas.Left=\"470\""); 
     sb.Append("  Template=\"{StaticResource DesignerItemTemplate}\">"); 
     sb.Append(" <Rectangle Fill=\"Blue\""); 
     sb.Append(" IsHitTestVisible=\"False\"/>"); 
     sb.Append("</ContentControl>"); 
     ContentControl cc= (ContentControl) XamlReader.Parse(sb.ToString()); 
     LayoutRoot.Children.Add(cc); 

    } 

Исключение:

$exception{"'Provide value on 'System.Windows.StaticResourceExtension' threw an exception.' Line number '1' and line position '258'."} System.Exception {System.Windows.Markup.XamlParseException} 

ответ

1

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

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

var contentControl = new ContentControl 
    { 
    Width = 130, 
    MinWidth = 50, 
    Height = 130, 
    MinHeight = 40 
    }; 

    Canvas.SetLeft(contentControl, 150); 
    Canvas.SetTop(contentControl, 470); 

    contentControl.Content = new Rectangle { Fill = new SolidColorBrush(Color.Blue) }; 

    LayoutRoot.Children.Add(contentControl); 

Сейчас этот пример кода, вероятно, не будет компилироваться как есть (у меня нет компилятора здесь), но вы получите идею. Просто создайте элементы управления в коде, как и другие классы.

+0

Да, это был мой первый подход, но у меня было не знаю, как установить свойство Template – jazza1000

+1

Ах, блестящий, теперь, когда у меня был другой ход, я вижу, что вы дали мне правильный ответ – jazza1000

1

Это код, который я закончил с использованием (спасибо Rune Grimstad) - это была установка свойства шаблона, который был хитрый немного для меня, чтобы выяснить

ContentControl cc = new ContentControl(); 
     ControlTemplate ct = new ControlTemplate(); 
     object rs = this.Resources["DesignerItemTemplate"]; 
     ct = (ControlTemplate)rs; 
     cc.Template = ct; 
     cc.Height = 10; 
     cc.Width = 10; 
     cc.Content = new Rectangle { Fill = new SolidColorBrush(Color.FromRgb(0,0,255)) }; 
     LayoutRoot.Children.Add(cc); 
     Canvas.SetLeft(cc, 300); 
     Canvas.SetTop(cc, 300);