MarkupExtension作为Template中的计算属性

ale*_*2k8 4 wpf templates markup-extensions

有这样的MarkupExtension

public class Extension1 : MarkupExtension
{
    private static int _counter = 0;

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return string.Format("Item {0}", _counter++);
    }
}
Run Code Online (Sandbox Code Playgroud)

和这个XAML

<ListBox>
  <ListBoxItem Content="{my:Extension1}"></ListBoxItem>
  <ListBoxItem Content="{my:Extension1}"></ListBoxItem>
  <ListBoxItem Content="{my:Extension1}"></ListBoxItem>
</ListBox>
Run Code Online (Sandbox Code Playgroud)

我得到这样的清单:

Item 1
Item 2
Item 3
Run Code Online (Sandbox Code Playgroud)

现在我尝试使用此Style生成相同的列表

<Style TargetType="ListBoxItem">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ListBoxItem">
                <TextBox Text="{my:Extension1}"></TextBox>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
Run Code Online (Sandbox Code Playgroud)

并有这样的XAML

<ListBox ItemsSource="{StaticResource data}"></ListBox>
Run Code Online (Sandbox Code Playgroud)

我明白了

Item 0
Item 0
Item 0
Run Code Online (Sandbox Code Playgroud)

所以{my:Extension1}仅评估一次.我可以创建一个将为每个项目评估的计算属性吗?

Tho*_*que 5

尝试从ProvideValue而不是字符串返回一个对象

菲尔是在正确的轨道上...其实,你需要返回thisProvideValue您的标记扩展从模板调用.这将导致为模板生成的每个控件评估标记扩展.要确定调用ProvideValue是否来自模板,您需要检查目标对象:在模板中,它将是类型System.Window.SharedDp.我写了一篇关于此的博客文章.