尝试在 PowerShell 中实现 IValueConverter 时出错 - XAML GUI 脚本 [英] Error trying to implement IValueConverter in PowerShell - XAML GUI script

查看:22
本文介绍了尝试在 PowerShell 中实现 IValueConverter 时出错 - XAML GUI 脚本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我错过了什么?我试图为我的基于 XAML 的 PowerShell 脚本实现转换器,但没有运气.我从 StackOverflow 等网站获取了一些信息.但在基于 powershell XAML 的 GUI 脚本中找不到一个转换器的成功实现.

What am I missing? I was trying to implement converters to my XAML-based PowerShell script but with no luck. I've picked up pieces of information from sites like StackOverflow. but couldn't find one successful implementation of a converter in powershell XAML-based GUI script.

在我正在测试转换器的代码中,它可以工作(您可以看到 2 个转换示例),这意味着 powershell 本身接受了新的转换器类型,购买此转换器无法在我的 xaml 代码中实现.

in the code I am testing the converter, and it works (you can see 2 examples for conversion) so that means that powershell itself accepted the new converter type, buy this converter cannot be implemented in my xaml code.

$src = @'
    using System;
    using System.Windows;
    using System.Windows.Data;
    using System.Globalization;

    namespace MyProject
    {

        public class DemoConverter : IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            {
                if (value == null)
                {
                    return "kuku";
                }
                else
                {            
                    return "bobo";
                }
            }
            public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            {   
                return value;
            }
        }
    }
'@

Add-Type -AssemblyName PresentationFramework    
Add-Type -TypeDefinition $src -ReferencedAssemblies PresentationFramework

#Checking that the new type works and convert is done...
$c = new-object MyProject.DemoConverter
$c.Convert("gg", $null, $null, $null)
$c.Convert(55, $null, $null, $null)

#Now declaring and loading the xaml
[xml]$XAML = @'

<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cnv="clr-namespace:MyProject" >
    <Window.Resources>
        <cnv:DemoConverter x:Key="TestConverter" />
    </Window.Resources>
    <Grid>     
        <TextBox x:Name="txtTestValue" Text="I'm here to show that xaml loading works!" />
    </Grid>
</Window>
'@

$reader=(New-Object System.Xml.XmlNodeReader $xaml) 

$Window=[Windows.Markup.XamlReader]::Load( $reader )

$Window.ShowDialog() | out-null

我不断收到此错误:

使用1"个参数调用Load"的异常:无法创建未知类型‘{clr-namespace:MyProject}DemoConverter’."

Exception calling "Load" with "1" argument(s): "Cannot create unknown type '{clr-namespace:MyProject}DemoConverter'."

如果我删除该行:<cnv:DemoConverter x:Key="TestConverter"/>它不会给出上述错误并且窗口将显示(但当然,xaml 中的转换将不可用),所以我想我在命名空间和/或程序集减速方面做错了 XAML 不喜欢的事情.

If I remove the line: <cnv:DemoConverter x:Key="TestConverter" /> It will not give the above error and the window will show (but of course, convertion in xaml will not be available), so I guess I'm doing something wrong with namespace and/or assembly deceleration that XAML doesn't like.

请注意,在我的 xaml 上,我还没有使用转换器.我只是想在尝试使用转换器之前克服上述错误.

Note that on my xaml I'm not yet using the converter. I just want to overcome the above error before trying to use the converter.

在此先感谢您!

推荐答案

我注册了 Stackoverflow 只是为了参与这个问题.

I signed up for Stackoverflow just so I could participate in this question.

在我在这里遇到这个问题之前,我搜索了 HOURS 来解决这个问题,然后我的希望破灭了,看到它已经在这里坐了将近一年没有答案.

I searched for HOURS for a solution to this before I ran across this question here, and then my hopes were dashed to see it's been sitting out here almost a year with no answer.

我之前发现了这个相关问题,它提供了我们试图用这个问题实现的基本解决方案,但没有提供任何有关使其实际工作的细节.如何从 powershell 使用 IValueConverter?

I had found this related question earlier, and it gives the basic solution we're trying to implement with this question, but doesn't give any details on making it actually work. How to use IValueConverter from powershell?

幸运的是,经过几个小时,并拼凑了很多其他信息,我终于解决了!

Luckily, after several more hours, and piecing together a lot of other info, I finally solved it!

它有 3 个部分.

  1. 通过 C# 代码添加的转换器类型不是表单的同一命名空间的一部分,即使您在 C# 类代码中指定了表单的命名空间.所以需要一个额外的 xmlns: 行来在表单中包含转换器类型的命名空间.然后在表单资源中定义转换器时,您引用该名称空间而不是表单自己的名称空间(通常是本地",但我看到您使用了cnv"的示例).此外,出于以下原因,您希望 C# 代码中的命名空间与表单自己的命名空间不同.(我不确定,但系统可能会因为 2 个不同的命名空间实际上在物理上分开而感到困惑.)
  2. 但是,即使添加了 xmlns: 行以包含转换器的命名空间,表单仍然无法找到它.这是因为,我发现,添加的转换器类型也被添加到不同的程序集中.显然,当使用Add-Type -TypeDefinition"添加自定义类型时,PowerShell 会创建自己的内存程序集并将类型添加到其中.因此,在添加的 xmlns: 行中包含转换器的命名空间,我们还必须为自定义转换器类型指定程序集.
  3. 但是,但是……更糟糕的是,这个编造"的程序集有一个随机生成的名称,并且每次运行脚本时程序集名称都不同.(我在任何地方都找不到这个事实的记录.我完全是偶然发现的.)那么,如果您不知道程序集名称,如何包含程序集名称?基本上做你所做的,在变量中创建新转换器对象的实例,然后检查该新对象变量的属性以确定程序集名称.然后使用字符串替换用程序集名称更新您的 XAML 字符串.

SO,请参阅我发布的更新代码,其中包含以下更改.正如原始海报所示,此示例并未显示转换器的运行情况,但脚本至少会运行并显示表单而不会出错,表明表单本身接受了 TextBox 中的转换器定义和用法.

SO, see the updated code I posted which has the following changes. As the original poster indicated, this example doesn't show the converter in action, but the script will at least run and display the form without error, indicating the the form itself accepted the converter definition and usage in the TextBox.

  • 将 C# 代码中的命名空间更改为 MyConverter,使其有所不同来自表单的 MyProject 命名空间.
  • 在创建转换器对象的 $c 实例的行中,我将命名空间更改为 MyConverter 而不是 MyProject,以匹配上面的新命名空间.
  • 添加了 $AssemblyName 变量以提取随机程序集名称.(我还注释掉了对 Convert 和 ConvertBack 的调用.)
  • 将 XAML 代码的 Here-String 更改为字符串变量 $inputXML,以便我们可以对其使用 Replace.稍后将转换为 xml 文档.
  • xlmns:Converter 行已添加以包含 MyConverter 命名空间.注意;assembly=myassembly"部分.myassembly"名称只是字符串 Replace 的占位符,以便以后轻松找到.
  • 在转换器 Window.Resources 的声明中,将cnv:"更改为Converter:"以匹配转换器类型的命名空间声明.
  • 添加了另一个文本框以显示包含转换器并且表单构建接受此.
  • 添加了 [xml]$XAML = $inputXML.... 行以转换为 xml 并替换为实际程序集名称.

代码

$src = @'
    using System;
    using System.Windows;
    using System.Windows.Data;
    using System.Globalization;

    namespace MyConverter
    {

        public class DemoConverter : IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            {
                if (value == null)
                {
                    return "kuku";
                }
                else
                {            
                    return "bobo";
                }
            }
            public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            {   
                return value;
            }
        }
    }
'@

Add-Type -AssemblyName PresentationFramework    
Add-Type -TypeDefinition $src -ReferencedAssemblies PresentationFramework

#Checking that the new type works and convert is done...
$c = new-object MyConverter.DemoConverter
$AssemblyName = $c.gettype().Assembly.FullName.Split(',')[0]
#$c.Convert("gg", $null, $null, $null)
#$c.Convert(55, $null, $null, $null)

#Now declaring and loading the xaml
$inputXML = @'

<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Converter="clr-namespace:MyConverter;assembly=myassembly"
xmlns:cnv="clr-namespace:MyProject" >
    <Window.Resources>
        <Converter:DemoConverter x:Key="TestConverter" />
    </Window.Resources>
    <Grid>     
        <TextBox x:Name="txtTestValue" Text="I'm here to show that xaml loading works!" />
        <TextBox x:Name="txtTestValue2" Text="{Binding Path=Whatever, Converter={StaticResource TestConverter}}" />
   </Grid>
</Window>
'@

[xml]$XAML = $inputXML -replace 'myassembly', $AssemblyName

$reader=(New-Object System.Xml.XmlNodeReader $xaml) 

$Window=[Windows.Markup.XamlReader]::Load( $reader )

$Window.ShowDialog() | out-null

这篇关于尝试在 PowerShell 中实现 IValueConverter 时出错 - XAML GUI 脚本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆