0

在这样的 XAML 中:

 <Button Tag="{Bindin Explain}"/>

在视图模型中:

private string explain = "";
public string Explain
{
    get { return explain; }
    set
    {
        if (explain != value)
        {
            explain = value;
            NotifyPropertyChanged("Explain");
        }
    }
}

但它不起作用,所以我从 MSDN 检查它:http: //msdn.microsoft.com/en-us/library/system.windows.frameworkelement.tag%28v=vs.95%29.aspx

因为该值是字符串类型,所以不能被 Tag 属性绑定。

解释是什么?

XAML 值

  • object* — Silverlight 对象或支持对象元素语法的自定义对象(支持类型必须是非抽象的,并且必须支持公共默认构造函数)。
  • string — 字符串值(可以是真正的字符串,也可以是支持从字符串进行类型转换的对象类型的输入)。

属性值
类型:System.Object — 预期值。此属性没有默认值。

备注:
依赖属性标识符字段:TagProperty

此属性类似于其他编程模型中的 Tag 属性。Tag 旨在提供一个预先存在的属性位置,您可以在其中存储有关任何 FrameworkElement 的一些基本自定义信息,而无需您从 FrameworkElement 或中间类派生。

由于此属性采用对象,因此需要使用属性元素将 XAML 中的 Tag 属性设置为具有类型转换器的对象以外的任何内容,例如字符串。以这种方式使用的对象通常不在标准 Silverlight XAML 命名空间内,因此可能需要映射外部命名空间才能作为 XAML 对象元素引入。

4

1 回答 1

1

您应该能够拥有比控件要求更具体的视图模型属性类型。并且“对象标签”尽可能不具体,所以它应该接受任何东西。

我敢打赌,这是因为 Dimitriy 所说的错字。如果没有,请尝试将 Mode=OneWay 添加到绑定中。我不记得默认情况下 silverlight 有两种或一种方式,但有时它也可以有所作为,因为双向绑定有更严格的要求。


编辑:MSDN 说:

由于此属性采用对象,因此需要使用属性元素将 XAML 中的 Tag 属性设置为具有类型转换器的对象以外的任何内容,例如字符串。

这个片段有一个非常奇怪的语法(至少对我来说,我不是英语母语)。理解其含义的关键在于:“属性元素用法”。让我标记句子的各个部分:

因为此属性需要一个对象 // ,所以在 XAML 中, // 需要使用属性元素 // 将 Tag 属性设置为 // 除了具有类型转换器的 // 对象之外的任何东西 // ,例如字符串。

它们的关键词是“XAML”和“属性元素”。你看,在 XAML 中有两个语法结构来设置属性。首先是“XML 属性”:

<TextBlock Text="my mom has a cat" Foreground="Violet" />

第二个是“XML 子元素”:

<TextBlock>
    <TextBlock.Text>
        my mom has a cat
    </TextBlock.Text>
    <TextBlock.Foreground>
        Violet
    </TextBlock.Foreground>
</TextBlock>

通常,第一个简称为按属性或按属性,第二个称为按属性或元素。请注意,即使属性或子元素仅包含文本(字符串!),XAML 解析器也足够聪明,知道如何转换值。该Text属性是字符串类型,所以它会直接给出一个文本,而它Foreground是一个画笔。曾经尝试在代码中设置前景或背景或填充颜色?你不能直接这样做。而不是Colors.Violet您必须创建 ie anew SolidColorBrush(Colors.Violet)并将其分配给属性。那么如何分配文本“紫罗兰色”?:) 在 XAML 中,解析器只是默默地使用适当的转换器 a Brush converter,它将字符串转换为适当的 Brush。

有了Tag财产,有一件不好玩的事情。它是一个object. XAML 解析器如何知道您想要拥有的确切类型的对象?你写“125599”。好的。是 Int32 吗?还是字符串?还是十六进制RGB颜色?

这就是 MSDN 试图警告您的原因 - 由于语法模糊而失败。XAML 会将所有设置Tag为字符串的文本值处理。如果你想让它写一个整数或颜色,你必须准确地说出你想运行什么转换:

xmlns:sys="clr-namespace:System"
....
<!-- those two are strings -->
<TextBlock Tag="1255599" />
<TextBlock>
    <TextBlock.Tag>
        115599
    </TextBlock.Tag>
</TextBlock>
....
<!-- those will be read as Int32 -->
<TextBlock Tag="{sys:Int32 1255599}" />
<TextBlock>
    <TextBlock.Tag>
        <sys:Int32>115599</sys:Int32>
    </TextBlock.Tag>
</TextBlock>

在后两者中,我命令 XAML 解析器从 System 命名空间创建 Int32 类型的对象。因此,文本将被解析为整数。

现在,看看这些例子:

<!-- I can put any object, right? -->
<TextBlock>
    <TextBlock.Tag>
        <TextBlock Foreground="Green">
           haha
        </TextBlock>
    </TextBlock.Tag>
</TextBlock>

<!-- I can put any object, right? -->
<TextBlock>
    <TextBlock.Tag>
        <MyClass>
              what happens to this text?
        </MyClass>
    </TextBlock.Tag>
</TextBlock>

诡异的?但是,嘿,Tag 可以带任何对象。在第一个中,我命令 XAML 解析器创建一个文本块,设置文本和颜色,并将这样的对象作为标记值 - 一切都很清楚。但是看第二个。这里会发生什么?内部文本如何转换为“MyClass”?

问题是,没人知道。嗯,差不多。如果 MyClass 是 Int32,则启动字符串到整数转换器,因为 Int32 在 .Net 框架内的某处注册了 TYPE CONVERTER。如果 MyClass 是 TextBlock - 内部文本设置为 TextProperty,因为 TextBlock在 .Net 框架的某处注册了一个默认属性。还有一个MyClass?我们不知道,编译器会抱怨,除非它在自己的源代码中某处注册了类似的东西。

请看最后四个例子。请注意我如何通过内联和“详细”语法分配 Int32。这是因为 Int32 具有关联的类型转换器,因此 Int32 告诉框架如何将字符串转换为 Int32。请参阅 TextBlocks 和 MyCLass 我做不到!我无法将 Tag 属性设置为“List”或“Grid”或“MyClass”类的对象,因为它们没有关联的类型转换器。该框架会看到一个表达式 Tag="{abc:MyClass mom has a cat}" 但它不知道如何将“mom has a cat”转换为“MyClass”。

我希望现在:

因为此属性需要一个对象 // ,所以在 XAML 中, // 需要使用属性元素 // 将 Tag 属性设置为 // 除了具有类型转换器的 // 对象之外的任何东西 // ,例如字符串。

更清楚一点:在 XAML 中,如果要分配没有关联类型转换器的对象,则必须使用宽属性分配语法并明确指定对象构造。但是,如果一个对象有一个类型转换器,一个字符串就是这样的对象,那么你可以通过简单的属性语法来分配它。

免责声明:请注意,我没有运行上述任何代码。可能存在小错误,类可能选择不当并且可能无法正常工作,但一般机制是可以的。如果不是,请给我留言。

于 2012-08-17T14:11:22.983 回答