0

我正在尝试创建一个WPF应用程序,允许您在屏幕上创建矩形,调整矩形大小并移动它们,并在单击按钮时添加新的可调整大小和可移动的矩形。

我对 WPF 了解不多,所以我在这里找到了一些调整形状大小的代码

这种调整大小的工作将,但我现在坚持如何动态创建控件的新版本。我正在使用一个处理调整大小的 ContentControl,它有一个用于显示的内部 Rectangle。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>

正是 Template 属性给了我问题——我如何动态地创建它。

我尝试将 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}
4

2 回答 2

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);

现在这个代码示例可能不会按原样编译(我这里没有编译器),但你明白了。只需像在任何其他类中一样在代码中创建控件。

于 2013-06-27T09:02:13.823 回答
1

这是我最终使用的代码(感谢 Rune Grimstad)——它设置了 Template 属性,这对我来说是个棘手的问题

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);
于 2013-06-27T09:37:25.343 回答