拖放后

时间:2016-04-29 11:35:20

标签: c# wpf xaml user-controls

我有一个带有WPF控件库的解决方案 - 其中包含一些UserControl - 以及一个WPF应用程序,该应用程序将使用来自库的UserControls。 我添加了库作为项目参考。 在WPF应用程序中,我有两个WPF Windows。 一个带有控件(如TooBox)和另一个,我想通过拖放传输/复制控件。 当我在第二个窗口上放下我的一个UserControls时,我通过使用XamlDesignerSerializationManager从拖动的元素中获取一个包含xaml的字符串。 然后我尝试使用StringReader和XmlReader从XAML-string中创建FrameworkElement。 在这一点,我得到一个System.Windows.Markup.XamlParseException,因为我在UserControl XAML中使用的名称“border”存在两次,无法注册。

有人可以解释为什么会这样吗?

这是其中一个UserControls的XAML:

<UserControl x:Class="WpfDesignerControlLibrary.ControlLabel"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:WpfDesignerControlLibrary"
             mc:Ignorable="d"
             d:DesignHeight="30"
             d:DesignWidth="150">
    <UserControl.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Resources.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </UserControl.Resources>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Border Name="border"
                Style="{StaticResource usercontrolBorderStyle}">
            <Label Name="label"
                   Margin="2">
                <TextBlock Name="textblock"
                           Text="Label"
                           TextWrapping="Wrap"/>
            </Label>
        </Border>
    </Grid>
</UserControl>

序列化拖动控件时从XamlDesignerSerializationManager获得的内容:

<ControlLabel Text="Label" ControlHorizontalContentAlignment="Left" ControlVerticalContentAlignment="Top" FontIsBold="True" FontStyleIsItalic="False" TextIsUnderlined="False" FontWeight="Bold" Name="label21" av:Canvas.Left="103" av:Canvas.Top="214" xmlns="clr-namespace:WpfDesignerControlLibrary;assembly=WpfDesignerControlLibrary" xmlns:av="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <ControlLabel.TextDecorations>
    <av:TextDecorationCollection />
  </ControlLabel.TextDecorations>
  <av:Grid>
    <av:Grid.ColumnDefinitions>
      <av:ColumnDefinition />
    </av:Grid.ColumnDefinitions>
    <av:Grid.RowDefinitions>
      <av:RowDefinition Height="*" />
    </av:Grid.RowDefinitions>
    <av:Border Name="border">
      <av:Border.Style>
        <av:Style TargetType="av:IFrameworkInputElement">
          <av:Style.Resources>
            <av:ResourceDictionary />
          </av:Style.Resources>
          <av:Setter Property="av:Border.BorderBrush">
            <av:Setter.Value>
              <av:SolidColorBrush>#FF4169E1</av:SolidColorBrush>
            </av:Setter.Value>
          </av:Setter>
          <av:Setter Property="av:Border.BorderThickness">
            <av:Setter.Value>
              <av:Thickness>1,1,1,1</av:Thickness>
            </av:Setter.Value>
          </av:Setter>
          <av:Setter Property="av:FrameworkElement.HorizontalAlignment">
            <av:Setter.Value>
              <x:Static Member="av:HorizontalAlignment.Stretch" />
            </av:Setter.Value>
          </av:Setter>
          <av:Setter Property="av:FrameworkElement.VerticalAlignment">
            <av:Setter.Value>
              <x:Static Member="av:VerticalAlignment.Stretch" />
            </av:Setter.Value>
          </av:Setter>
        </av:Style>
      </av:Border.Style>
      <av:Label Name="label" Margin="2,2,2,2">
        <av:TextBlock Text="Label" TextWrapping="Wrap" Name="textblock" />
      </av:Label>
    </av:Border>
  </av:Grid>
</ControlLabel>

这是我将XAML作为拖出控件中的字符串的方法:

public string SerializeControlToXaml(FrameworkElement control)
{
    StringBuilder outstr = new StringBuilder();

    //this code need for right XML fomating 
    XmlWriterSettings settings = new XmlWriterSettings();
    settings.Indent = true;
    settings.OmitXmlDeclaration = true;
    XamlDesignerSerializationManager dsm =
        new XamlDesignerSerializationManager(XmlWriter.Create(outstr, settings));
    //this string need for turning on expression saving mode 
    dsm.XamlWriterMode = XamlWriterMode.Expression;
    System.Windows.Markup.XamlWriter.Save(control, dsm);

    string xaml = outstr.ToString();
    return xaml;
}

最后产生错误的方法(在最后一行代码中):

public object DeserializeXaml(string xaml)
{
    StringReader stringReader = new StringReader(xaml);
    XmlReader xmlReader = XmlReader.Create(stringReader);
    return System.Windows.Markup.XamlReader.Load(xmlReader);
}

1 个答案:

答案 0 :(得分:0)

我找到了。 您必须从UserControl定义中删除所有名称并使用ViewModel。