Windows Phone - 按钮标签绑定 - MSDN的含义是什么?

时间:2012-08-17 13:56:47

标签: c# xaml binding windows-phone

在这样的XAML中:

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

在ViewModel中:

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对象元素引入。

1 个答案:

答案 0 :(得分:1)

您应该能够拥有比控件请求更具体的viewmodel属性类型。而对象标签&#39;至少是具体的,所以它应该接受任何东西。

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


编辑:MSDN说:

  

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

这个片段有一个非常奇怪的语法(至少对我而言,我不是英国本土的)。理解其含义的关键在于:&#34;属性元素用法&#34;。让我标记句子的部分:

  

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

关键词是&#34; XAML&#34;和&#34;属性元素&#34;。你会看到,在XAML中有两种语法结构来设置属性。首先是&#39; XML属性&#39;:

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

,第二个是&#34; XML子元素&#34;:

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

通常,第一个是by-attribute或by-property,第二个是by-property-element。请注意,即使属性或子元素仅包含文本(字符串!),XAML解析器也足够聪明,可以知道如何转换值。 Text属性的类型为String,因此它将直接给出文本,而Foreground是一个刷子..曾经在代码中尝试设置前景或背景或填充颜色?你不能直接这样做。而不是Colors.Violet您必须创建一个new SolidColorBrush(Colors.Violet)并将其分配给该属性。那么如何分配文本&#34;紫罗兰&#34;? :)在XAML中,解析器只是默默地使用一个适当的转换器Brush converter,它将字符串转换为正确的Brush。

使用Tag属性,这是一个不可靠的事情。这是一个object。 XAML解析器如何知道您想要的确切类型的对象?你写&#34; 125599&#34;。好。是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解析器创建一个文本块,设置文本和颜色,并将这个对象作为Tag值 - 一切都很清楚。但看看第二个。这里发生了什么?如何转换内部文本将转换为&#34; MyClass&#34;?

问题是,没有人知道。好吧,差不多。如果MyClass是Int32,那么一个string-to-int转换器会激活,因为Int32在.Net框架内的某处注册了一个TYPE CONVERTER。如果MyClass是一个TextBlock - 内部文本设置为TextProperty,因为TextBlock在.Net框架中的某处注册了DEFAULT PROPERTY。还有一个MyClass?我们不知道,并且编译器会抱怨,unles它在自己的源代码中有一个类似的东西注册。

请看最后四个例子。请注意我如何分配Int32内联和通过&#34;详细&#34;句法。这是因为Int32有一个关联的类型转换器,因此Int32告诉框架如何将字符串转换为Int32。请注意,对于TextBlocks和MyCLass,我无法做到!我无法将Tag属性设置为类的对象&#34; List&#34;或者&#34;网格&#34;或&#34; MyClass&#34;,因为它们没有关联的类型转换器。框架会看到一个表达式Tag =&#34; {abc:MyClass mom有一只猫}&#34;但它不知道如何转换一个&#34;妈妈有一只猫&#34;进入&#34; MyClass&#34;。

我希望现在:

  

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

更清楚一点:在XAML中,如果要分配没有关联类型转换器的对象,则必须使用wide属性-assignement语法并明确指定对象constrction。但是,如果对象具有类型转换器,则字符串就是这样的对象,然后您可以通过简短的属性语法来分配它。

声明: 请注意,我没有运行上述任何代码。可能存在小错误,类可能选择不当而且可能不起作用,但一般机制都可以。如果没有,请给我留言。