【问题标题】:How to render a databound XAML control to a native XAML drawing如何将数据绑定 XAML 控件呈现为本机 XAML 绘图
【发布时间】:2011-02-10 14:26:17
【问题描述】:

我有一个这样的数据绑定 XAML 控件:

<UserControl>
    <TextBlock Text="{Binding Text}" />
</UserControl>

并希望它像这样呈现为“绘图”:

<UserControl>
    <TextBlock Text="Actual text value" />
</UserControl>

有谁知道如何从任意控件中提取图形?

更新: 这个问题似乎不是很清楚。所以我试着解释一下。 输入是一个带有数据绑定的 XAML 控件。现在我想将其转换为纯 XAML 而无需任何数据绑定。输出可以写入磁盘并由任何理解 XAML 的应用程序显示,而无需绑定到任何东西。

所以解决方案应该是这样的:

FrameworkElementinput = (FrameworkElement)XamlReader.Read(inputFile);
input.DataContext = dataObject;
FrameworkElement output = ConvertToNative(input);
XamlWriter.Write(outputFile, output);

我正在寻找“ConvertToNative”的实现

【问题讨论】:

  • 对绘画的意思感到困惑?在您的示例中,绑定很简单,是对 Text 属性中应提供的内容的运行时解决方案;而您在第二个示例中在编译时提供值
  • 您在何时何地想要这个?从 Visual Studio 2010 Designer 内部产生的 DesignTime 数据?
  • @Aaron 我不知道确切的术语。对于“绘图”,我的意思是纯 XAML,没有任何扩展,例如绑定。 “绘图”应该可以在数据未知的上下文中加载。 (就像外国申请一样。)
  • @Meleak 这需要在运行时完成
  • @Michael 当您将数据绑定到模型上的给定属性时,数据可以来自任何地方,并将在运行时执行。所以你可以有 {Binding GetMeSomethingFarFarAway} 其中 GetMeSomethingFarFarAway 是你模型上的一个属性,它反过来调用一个服务,然后调用 Flickr 并获取一个图像名称。

标签: c# wpf xaml data-binding binding


【解决方案1】:

如果您要为 UserControls 执行此操作,请确保首先删除 x:Class 属性,否则您将获得 XamlParseException

您可以使用XamlReader.Load 加载Xaml 文件,当您使用XamlWriter.Save 保存它时,绑定将转换为它们的实际值。虽然让绑定更新似乎有些麻烦,所以我通过订阅 Loaded 事件并将其添加到 UI 中的容器中来解决这个问题,并在事件处理程序中从容器中删除 if 然后保存它。不过,这可能可以以更好的方式解决..

private void SomeMethod()
{
    CreateXamlWithBindingValues("UserControl1.xaml", "UserControl1_Saved.xaml");
}
private void CreateXamlWithBindingValues(string sourcePath, string savePath)
{
    StreamReader streamReader = new StreamReader(sourcePath);
    StringReader stringReader = new StringReader(streamReader.ReadToEnd());
    XmlReader xmlReader = XmlReader.Create(stringReader);
    FrameworkElement loadedObject = (FrameworkElement)XamlReader.Load(xmlReader);
    loadedObject.DataContext = UserControlViewModel;

    RoutedEventHandler routedEventHandler = null;
    routedEventHandler = new RoutedEventHandler(delegate
    {
        loadedObject.Loaded -= routedEventHandler;
        grid1.Children.Remove(loadedObject);

        string savedObject = XamlWriter.Save(loadedObject);
        StreamWriter streamWriter = new StreamWriter(savePath);
        streamWriter.Write(savedObject);
        streamWriter.Close();
    });
    loadedObject.Loaded += routedEventHandler;
    grid1.Children.Add(loadedObject);
}

保存前的 Xaml

<UserControl 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" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
        <TextBlock Text="{Binding Text}"/>
    </Grid>
</UserControl>

保存后的 Xaml 如您所见,没有换行符,但 Text 值是绑定产生的值

<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"><Grid><TextBlock Text="Actual Text Value" /></Grid></UserControl>

保存前的 Xaml

<Grid Name="grid1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
    <Button Content="{Binding MyContent}"/>
</Grid>

保存后的 Xaml

<Grid Name="grid1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"><Button>Actual Content</Button></Grid>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-04-29
    • 1970-01-01
    • 2011-04-01
    • 1970-01-01
    • 2012-02-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多