繁体   English   中英

拖放后无法注册WPF UserControl中的子控件的名称

[英]Names of subcontrols in WPF UserControl cannot be registered after drag-and-drop

我有一个带有WPF控件库(其中包含一些UserControls)和WPF应用程序的解决方案,该应用程序将使用库中的UserControls。 我将库添加为项目参考。 在WPF应用程序中,我有两个WPF Windows。 一个带有控件(如TooBox),另一个带有我想通过拖放将控件转移/复制到的控件。 当我在第二个窗口上放置一个UserControls时,通过使用XamlDesignerSerializationManager从拖动的元素中获取带有xaml的字符串。 然后,我尝试使用StringReader和XmlReader从XAML字符串创建一个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);
}

我发现了。 您必须从UserControl定义中删除所有名称,然后使用ViewModel。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM