如何更改PowerShell显示自定义类型属性的方式?

时间:2013-07-10 17:20:15

标签: powershell

在PowerShell中,当我在表(或列表)中查看自定义MyStuff.Document类型时,使用我的Content函数不会显示其ToString()属性。而是PowerShell迭代集合并显示其中的项目。我希望它使用我的ToString()函数。

示例:

$doc = New-Object MyStuff.Document
$doc.Content.Add("Segment 1")
$doc.Content.Add("Segment 2")

$doc | select Content

目前显示:

Content
-------
{Segment 1, Segment 2}

当我希望它显示时:

Content
-------
something custom

“自定义内容”是我ToString()函数的输出。

我已经挖掘了*.format.ps1xml文件,我认为这是我需要使用的文件,但我无法弄清楚如何做我想做的事情。 Update-TypeData看起来也很有希望,但我还没有好运。

非常感谢任何帮助。

这些是我正在使用的自定义类型:

namespace MyStuff
{
    public class Document
    {
        public string Name { get; set; }
        public FormattedTextBlock Content { get; set; }
    }

    public class FormattedTextBlock : ICollection<FormattedTextSegment>
    {
        public void Add(string text)
        {
            this.Add(new FormattedTextSegment() { Text = text });
        }

        // ... ICollection implementation clipped

        public override string ToString()
        {
            // ... reality is more complex
            return "something custom";
        }
    }

    public class FormattedTextSegment
    {
        public string Text { get; set; }

        public override string ToString()
        {
            return Text;
        }
    }
}

更新

要清楚,我知道像$doc | select @{ Expression = { $_.Content.ToString() }; Label = "Content" }这样的策略。我正在寻找告诉PowerShell默认情况下如何格式化我的属性。

1 个答案:

答案 0 :(得分:1)

这里有两个问题。

首先,当你执行Select -Property Content时,你真正告诉powershell的是“请给我一个带有所选属性的新对象以便进一步处理”。这样可以继续管道。

其次,如果管道结束,并且没有其他地方放置数据,则会发生格式化魔术。例如,$doc | Select Content | format-table将显示您现在看到的显示。然而,format-table收到的是具有名为Selected.MyStuff.Document的动态类型的PSCustomObject。您可以为此创建魔术类型信息,但由于Selected.MyStuff.Document是动态的,因此您的格式信息很可能不正确。

或者,您可以执行$doc.Content.ToString()之类的操作,假设您只有一个$ doc,或者如果您拥有MyStuff.Document个对象的集合$doc | % { $_.Content.ToString() },则可以执行此操作。这两个都失去了标题。

如果要格式化整个MyStuff.Document对象(无选择):$doc | format-table,您可以在format.ps1xml文件中使用以下内容并发生魔术。注意,我只为MyStuff.Document类型实现了Format-Table。您应该可以为FormattedTextBlock执行类似的操作。

<?xml version="1.0" encoding="utf-8" ?>
<Configuration>
    <ViewDefinitions>
        <View>
            <Name>MyStuff.Document</Name>
            <ViewSelectedBy>
                <TypeName>MyStuff.Document</TypeName>
            </ViewSelectedBy>
            <TableControl>
                <TableHeaders>
                    <TableColumnHeader>
                        <Label>Name</Label>
                    </TableColumnHeader>
                    <TableColumnHeader>
                        <Label>Content</Label>
                    </TableColumnHeader>
                </TableHeaders>
                <TableRowEntries>
                    <TableRowEntry>
                        <TableColumnItems>
                            <TableColumnItem>
                                <Alignment>Left</Alignment>
                                <PropertyName>Name</PropertyName>
                            </TableColumnItem>
                            <TableColumnItem>
                                <Alignment>Left</Alignment>
                                <ScriptBlock>$_.Content.ToString()</ScriptBlock> 
                            </TableColumnItem>
                        </TableColumnItems>
                    </TableRowEntry>
                </TableRowEntries>
            </TableControl>
        </View>
    </ViewDefinitions>
</Configuration>