1

MyStuff.Document在 PowerShell 中,当我在表(或列表)中查看我的自定义类型时,它的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 默认情况下如何格式化我的属性。

4

1 回答 1

2

这里有两个问题。

首先,当您这样做时Select -Property Content,您真正告诉 powershell 的是“请给我一个具有所选属性的新对象以供进一步处理”。这有效,因此您可以继续使用管道。

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

或者,您可以不使用 select,而是$doc.Content.ToString()假设您只有一个 $doc,或者如果您有一组MyStuff.Document对象,$doc | % { $_.Content.ToString() }. 这些都失去了标题。

如果您想格式化整个 MyStuff.Document 对象(没有 Select):,$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>
于 2013-07-15T01:45:25.910 回答