绑定Silverlight 3 dataInput的描述属性:DescriptionViewer

时间:2010-01-06 17:02:37

标签: silverlight data-binding silverlight-3.0

Silverlight的 dataInput:Label dataInput:DescriptionViewer 控件通过绑定到TextBox的功能提供了一个有用的功能。我没有使用System.ComponentModel.DataAnnotations.DisplayAttribute对我的标签和描述的文本内容进行硬编码,而是将这些属性绑定到包含管理员可编辑文本的类的属性。这适用于Label,但不适用于DescriptionViewer。

具体来说,这个标签有效:

<dataInput:Label Grid.Row="00" Grid.Column="0" 
Target="{Binding ElementName=inpStatus}"
Content="{Binding StatusLabel}"  IsRequired="true" />

但是这个DescriptionViewer是不可见的:

<dataInput:DescriptionViewer Grid.Row="00" Grid.Column="3" 
Target="{Binding ElementName=inpStatus}" 
Name="dvBound2" Description="{Binding Path=StatusDescription}" /> 

当我删除对TextBox的绑定时,会显示DescriptionViewer:

<dataInput:DescriptionViewer Grid.Row="00" Grid.Column="2" 
Name="dvBound1" Description="{Binding Path=StatusDescription}" /> 

是否可以将DescriptionViewer绑定到TextBox和备用描述源?

提前致谢!

MainPage.xaml中:

<UserControl x:Class="DataInputDemo.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:controlsToolkit="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Toolkit"  
    xmlns:dataInput="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.Input"
    xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"  
    mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480">
  <Grid x:Name="LayoutRoot">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="142"></ColumnDefinition>
            <ColumnDefinition Width="100"/>
            <ColumnDefinition Width="24"></ColumnDefinition>
            <ColumnDefinition Width="24"></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="30"></RowDefinition>
            <RowDefinition Height="30"></RowDefinition>
        </Grid.RowDefinitions>

        <dataInput:Label             Grid.Row="00" Grid.Column="0" 
            Target="{Binding ElementName=inpStatus}"
            Content="{Binding StatusLabel}"  IsRequired="true" />

        <TextBox                     Grid.Row="00" Grid.Column="1" 
            Text="{Binding Mode=TwoWay, NotifyOnValidationError=True, ValidatesOnExceptions=True, Path=Status}"
            Name="inpStatus" MaxLength="025" 
            BindingValidationError="_BindingValidationError" />

        <dataInput:DescriptionViewer Grid.Row="00" Grid.Column="2" 
            Name="dvBound1" Description="{Binding Path=StatusDescription}" />

        <!-- Following DescriptionViewer is not shown. -->
        <dataInput:DescriptionViewer Grid.Row="00" Grid.Column="3" 
            Target="{Binding ElementName=inpStatus}" 
            Name="dvBound2" Description="{Binding Path=StatusDescription}" />

        <dataInput:ValidationSummary Grid.Row="01" Grid.Column="0" 
            Grid.ColumnSpan="4" Name="VS1" />

    </Grid>
</UserControl>

MainPage.xaml.vb:

Partial Public Class MainPage
    Inherits UserControl

    Public myDataClass = New DataClass

    Public Sub New()
        InitializeComponent()
        myDataClass.status = "Default Status"
        myDataClass.StatusLabel = "Status Label"
        myDataClass.StatusDescription = "Status Description"
        LayoutRoot.DataContext = myDataClass
    End Sub

    Private Sub _BindingValidationError(ByVal sender As Object, ByVal e As ValidationErrorEventArgs)
    End Sub

End Class

DataClass.vb:

Imports System.Collections.ObjectModel
Imports System.ComponentModel
Imports System.Runtime.Serialization
Imports System.ComponentModel.DataAnnotations
Imports System.Windows.Controls

Public Class DataClass

    Implements INotifyPropertyChanged

    Public Event PropertyChanged As PropertyChangedEventHandler _
        Implements INotifyPropertyChanged.PropertyChanged

    Private Sub NotifyPropertyChanged(ByVal info As String)
        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(info))
    End Sub

    Function ValidateEntry(ByVal fieldname As String, ByRef value As Object) As Object
        Dim ctx As New ValidationContext(Me, Nothing, Nothing)
        ctx.MemberName = fieldname
        Validator.ValidateProperty(value, ctx)
        Return value
    End Function

    <DataMember()> _
    <Required()> _
    <StringLength(100)> _
    Public Property Status() As String
        Get
            Return _Status
        End Get
        Set(ByVal value As String)
            _Status = ValidateEntry("Status", value)
            NotifyPropertyChanged("")
        End Set
    End Property
    Private _Status As String

    <DataMember()> _
    Public Property StatusLabel() As String
        Get
            Return _StatusLabel
        End Get
        Set(ByVal value As String)
            _StatusLabel = value
            NotifyPropertyChanged("")
        End Set
    End Property
    Private _StatusLabel As String

    <DataMember()> _
    Public Property StatusDescription() As String
        Get
            Return _StatusDescription
        End Get
        Set(ByVal value As String)
            _StatusDescription = value
            NotifyPropertyChanged("")
        End Set
    End Property
    Private _StatusDescription As String

End Class

1 个答案:

答案 0 :(得分:1)

我使用此标记与DescriptionViewer完全相同:

<TextBox x:Name="UserNameTextBox" Text="{Binding UserName, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true, UpdateSourceTrigger=Explicit}" Grid.Column="1" Grid.Row="1"></TextBox>
<dataInput:DescriptionViewer Target="{Binding ElementName=UserNameTextBox}" Description="{Binding Path=CreateUserResources.UserNameDescription, Source={StaticResource GlobalResources}}" Grid.Column="2" Grid.Row="1"></dataInput:DescriptionViewer>

在将Description绑定到其资源之前,它是标记中的纯字符串,它确实有效。

要解决此问题,我已将DescriptionViewer的PropertyPath设置为绑定位于Target控件上的属性名称。它现在正常工作。

<TextBox x:Name="UserNameTextBox" Text="{Binding UserName, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true, UpdateSourceTrigger=Explicit}" Grid.Column="1" Grid.Row="1"></TextBox>
<dataInput:DescriptionViewer Target="{Binding ElementName=UserNameTextBox}" PropertyPath="Text" Description="{Binding Path=CreateUserResources.UserNameDescription, Source={StaticResource GlobalResources}}" Grid.Column="2" Grid.Row="1"></dataInput:DescriptionViewer>

如果您使用的是MVVM,请确保PropertyPath与您的演示者模型的属性不匹配。我没有调查,但我有一个实例,我被迫更改我的演示者的属性名称,使其工作。似乎控件试图从我的演示者的属性而不是目标控件解析元数据。

希望这有帮助。