如何包括原始的xaml文件,这不是一个资源?

ie3xauqp  于 2023-01-06  发布在  其他
关注(0)|答案(4)|浏览(148)

我有很多来自Visual Studio Image Library的XAML文件。下面是其中一个文件的内容-Add_16xMD.xaml

<!-- This file was generated by the AiToXaml tool.-->
<!-- Tool Version: 14.0.22307.0 -->
<Viewbox Width="16" Height="16" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
  <Rectangle Width="16" Height="16">
    <Rectangle.Fill>
      <DrawingBrush>
        <DrawingBrush.Drawing>
          <DrawingGroup>
            <DrawingGroup.Children>
              <GeometryDrawing Brush="#00FFFFFF" Geometry="F1M16,16L0,16 0,0 16,0z" />
              <GeometryDrawing Brush="#FFF6F6F6" Geometry="F1M10,7L14,7 14,10 10,10 10,14 7,14 7,10 3,10 3,7 7,7 7,3 10,3z" />
              <GeometryDrawing Brush="#FF388A34" Geometry="F1M13,8L9,8 9,4 8,4 8,8 4,8 4,9 8,9 8,13 9,13 9,9 13,9z" />
            </DrawingGroup.Children>
          </DrawingGroup>
        </DrawingBrush.Drawing>
      </DrawingBrush>
    </Rectangle.Fill>
  </Rectangle>
</Viewbox>

我想把它包含到我的WPF项目中,并在我的应用程序中使用。我不想复制粘贴代码,我不想修改这些文件 Package 他们与ResourceDictionary
有什么办法能让我做到吗?

dly7yett

dly7yett1#

只需将它们作为简单的文件资源包含在应用中,然后通过XamlReader示例传递它们,该示例将为您提供根项的示例(在本例中为ViewBox)。
https://blogs.msdn.microsoft.com/ashish/2007/08/14/dynamically-loading-xaml
简而言之,这样做...

StreamReader mysr = new StreamReader("SomeFile.xaml");
ViewBox myLoadedViewBox = XamlReader.Load(mysr.BaseStream) as ViewBox;
xkrw2x1b

xkrw2x1b2#

选项1:使用. svg图标

  • Visual Studio Image Library * 包含所有图标的SVG版本。您可以在SharpVectors nuget包的帮助下简单地使用它们(更多详细信息请参阅answer)。

1.将SVG文件添加到项目中(例如"Icons"子文件夹中),并将其Build Action属性设置为Resource
1.在代码中使用它:

<Window x:Class="WpfApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:svgc="http://sharpvectors.codeplex.com/svgc/"
        xmlns:local="clr-namespace:WpfApp"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <StackPanel>
            <Button Height="100">
                <svgc:SvgViewbox Source="/Icons/Checkmark_16x.svg"/>
            </Button>
            <ContentControl Height="100">
                <svgc:SvgViewbox Source="/Icons/CollapseAll_16x.svg"/>
            </ContentControl>
            <Label Height="100">
                <svgc:SvgViewbox Source="/Icons/Refresh_16x.svg"/>
            </Label>
        </StackPanel>
    </Grid>
</Window>

选项2:直接使用. xaml图标文件

1.将icon.xaml文件添加到您的项目中,例如"Icons"子文件夹中,并将其Build Action属性设置为Resource
1.创建转换器:

using System;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Markup;

namespace TestApp
{
    class XamlIconToViewBoxConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            var stream = System.Windows.Application.GetResourceStream(new Uri((string)parameter, UriKind.Relative)).Stream;
            var viewBox = XamlReader.Load(stream) as Viewbox;

            // Optional:
            // we set Height and Width to "Auto" to let an icon scale, because in the <icon>.xaml file its size is explicitly specified as 16x16
            viewBox.Height = double.NaN;
            viewBox.Width = double.NaN;

            return viewBox;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

1.按以下方式使用XAML代码中的图标:

<Window x:Class="TestApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:TestApp"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.Resources>
        <local:XamlIconToViewBoxConverter x:Key="XamlIconToViewBoxConverter"/>
    </Window.Resources>
    <Grid>
        <StackPanel>
            <Button Height="100" Content="{Binding Converter={StaticResource XamlIconToViewBoxConverter},ConverterParameter='/Icons/EditInput_16x.xaml'}"/>
            <ContentControl Height="100" Content="{Binding Converter={StaticResource XamlIconToViewBoxConverter},ConverterParameter='/Icons/ErrorSquiggleInactive_16x.xaml'}"/>
            <Label Height="100" Content="{Binding Converter={StaticResource XamlIconToViewBoxConverter},ConverterParameter='/Icons/FirstOfFourColumns_16x.xaml'}"/>
        </StackPanel>
    </Grid>
</Window>

还有一个类似的answer,但它不是ViewBox,而是使用XAML中指定为DrawingImage的图标

选项3:使用资源字典

1.将Icons.xaml ResourceDictionary添加到项目中,将XAML图标中的内容复制粘贴到项目中,并使用x:Key属性为每个图标分配唯一键

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <!-- Checkmark_16x.xaml -->
    <Viewbox x:Key="Checkmark_16x" Width="16" Height="16" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
        <Rectangle Width="16" Height="16">
            <Rectangle.Fill>
                <DrawingBrush>
                    <DrawingBrush.Drawing>
                        <DrawingGroup>
                            <DrawingGroup.Children>
                                <GeometryDrawing Brush="#00FFFFFF" Geometry="F1M16,16L0,16 0,0 16,0z" />
                                <GeometryDrawing Brush="#FFF6F6F6" Geometry="F1M6.0003,9.1717L2.7073,5.8787 0.000300000000000189,8.5857 0.000300000000000189,8.8277 6.0003,14.8277 16.0003,4.8287 16.0003,4.5857 13.2933,1.8787z" />
                                <GeometryDrawing Brush="#FF388A34" Geometry="F1M14.707,4.707L6,13.414 1.293,8.707 2.707,7.293 6,10.586 13.293,3.293z" />
                            </DrawingGroup.Children>
                        </DrawingGroup>
                    </DrawingBrush.Drawing>
                </DrawingBrush>
            </Rectangle.Fill>
        </Rectangle>
    </Viewbox>

    <!-- Refresh_16x.xaml -->
    <Viewbox x:Key="Refresh_16x" Width="16" Height="16" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
        <Rectangle Width="16" Height="16">
            <Rectangle.Fill>
                <DrawingBrush>
                    <DrawingBrush.Drawing>
                        <DrawingGroup>
                            <DrawingGroup.Children>
                                <GeometryDrawing Brush="#00FFFFFF" Geometry="F1M16,16L0,16 0,0 16,0z" />
                                <GeometryDrawing Brush="#FFF6F6F6" Geometry="F1M16,8C16,12.411 12.411,16 8,16 3.589,16 0,12.411 0,8 0,6.597 0.384,5.212 1.088,4L0,4 0,0 8,0 8,8 4,8C4,10.206 5.794,12 8,12 10.206,12 12,10.206 12,8 12,6.656 11.331,5.41 10.21,4.666L9.377,4.112 11.592,0.78 12.425,1.333C14.663,2.822,16,5.314,16,8" />
                                <GeometryDrawing Brush="#FF00529C" Geometry="F1M15,8C15,11.859 11.859,15 8,15 4.14,15 1,11.859 1,8 1,6.076 1.801,4.292 3.121,3L1,3 1,1 7,1 7,7 5,7 5,4.002C3.766,4.931 3,6.401 3,8 3,10.757 5.243,13 8,13 10.757,13 13,10.757 13,8 13,6.321 12.164,4.763 10.764,3.833L11.871,2.167C13.83,3.469,15,5.649,15,8" />
                            </DrawingGroup.Children>
                        </DrawingGroup>
                    </DrawingBrush.Drawing>
                </DrawingBrush>
            </Rectangle.Fill>
        </Rectangle>
    </Viewbox>

    <!-- CollapseAll_16x.xaml -->
    <Viewbox x:Key="CollapseAll_16x" Width="16" Height="16" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
        <Rectangle Width="16" Height="16">
            <Rectangle.Fill>
                <DrawingBrush>
                    <DrawingBrush.Drawing>
                        <DrawingGroup>
                            <DrawingGroup.Children>
                                <GeometryDrawing Brush="#00f6f6f6" Geometry="M16,16H0V0H16Z" />
                                <GeometryDrawing Brush="#FFf6f6f6" Geometry="M1,15V2H2V0H16V14H14v1Z" />
                                <GeometryDrawing Brush="#FF424242" Geometry="M2,14H13V3H2ZM3,4h9v9H3ZM15,1V13H14V2H3V1Z" />
                                <GeometryDrawing Brush="#FF00539c" Geometry="M11,9H4V8h7Z" />
                            </DrawingGroup.Children>
                        </DrawingGroup>
                    </DrawingBrush.Drawing>
                </DrawingBrush>
            </Rectangle.Fill>
        </Rectangle>
    </Viewbox>
</ResourceDictionary>

1.按以下方式使用XAML代码中的图标:

<Window x:Class="WpfApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:svgc="http://sharpvectors.codeplex.com/svgc/"
        xmlns:local="clr-namespace:WpfApp"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Icons.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>
    <Grid>
        <StackPanel>
            <Button Height="100" Content="{StaticResource Checkmark_16x}"/>
            <ContentControl Height="100" Content="{StaticResource CollapseAll_16x}"/>
            <Label Height="100" Content="{StaticResource Refresh_16x}"/>
        </StackPanel>
    </Grid>
</Window>
vcudknz3

vcudknz33#

最后我使用了上面@PolarBear的选项2的变体:
XAML(ImageKey是指enum):

<RadioButton 
    ToolTip="Container"
    VerticalContentAlignment="Bottom" 
    Content="{Binding Source={x:Static views:ImageKey.ClassLibrary}, Converter={StaticResource imageConverter}}"/>

转换器:

public class ImageConverter : IValueConverter
{
    private readonly Dictionary<ImageKey, object> _LoadedComponents = new();

    public object Convert(
        object value,
        Type targetType,
        object parameter,
        CultureInfo culture)
    {
        if (value is not ImageKey imageKey)
            return Binding.DoNothing;

        var resourceUrl = $"/images/{value}.xaml";
        var resourceUri = new Uri(resourceUrl, System.UriKind.Relative);
        if (!_LoadedComponents.TryGetValue(imageKey, out var component))
        {
            component = Application.LoadComponent(resourceUri);
            _LoadedComponents[imageKey] = component;
        }
        else
        {
            component = XamlReader.Parse(XamlWriter.Save(component));
        }

        return component;
    }

    public object ConvertBack(
        object value,
        Type targetType,
        object parameter,
        CultureInfo culture) =>

        throw new NotSupportedException();
}

public enum ImageKey
{
    None,
    CarIcon,
    UserIcon
}
vyu0f0g1

vyu0f0g14#

您可以做的另一件事是添加一个资源字典,然后添加对感兴趣的文件的引用。换句话说,您不是打开每个文件并 Package 它,而是创建一个引用所有感兴趣的资源文件的资源字典。

<ResourceDictionary>
    [Ref to file 1.xaml]
    [Ref to file 2.xaml]
    [Ref to file 3.xaml]
</ResourceDictionary>

我手边没有确切的语法,但应该很容易找到,因为一直都在使用引用。

相关问题