Привязка Silverlight 3 описательный атрибут dataInput: DescriptionViewer - PullRequest
1 голос
/ 06 января 2010

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, открывается окно DescriptionView:

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

Должна ли быть возможность привязать DescriptionViewer как к TextBox, так и к альтернативному источнику Description?

Заранее спасибо!

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 Ответ

1 голос
/ 04 августа 2010

У меня была точно такая же проблема с 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 к его ресурсу это была простая строка в разметке, и она работала.

Чтобы решить эту проблему, я установил PropertyPath для DescriptionViewer с именем свойства, в котором привязка находится в элементе управления 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 не соответствует свойству вашей модели презентатора. Я не проводил расследования, но у меня был случай, когда я был вынужден изменить имя свойства моего докладчика, чтобы оно работало. Похоже, что элемент управления пытался проанализировать метаданные из свойства моего докладчика вместо целевого элемента управления.

Надеюсь, это поможет.

...