2014-07-10 8 views
5

verwendet Ich bin ein Anfänger mit XAML (für MVVM ANSATZ) mit Silverlight. Ich lese mehrere Dokumente und bin ein wenig verwirrt über alles. Ich würde wirklich schätzen, wenn jemand den Unterschied zwischen den folgenden erklären könnte.Unterschied in XAML Bedingungen für die Bindung

Angenommen meine XAML ist:

xmlns:viewmodel="clr-namespace:smallMVVM" 
    ...... 
    ...... 
<UserControl.Resources> 
     <viewmodel:ViewModel x:Key="ViewModel"/> 
     <viewmodel:DatetimeToDateConverter x:Key="MyConverter"/> 
</UserControl.Resources> 

Nun, was ist der Unterschied zwischen:

  1. ich in MainPage.cs bedeuten, wenn ich "this.DataContext = new ViewModel();" tun. Und in MainPage.xaml wenn ich folgend <Grid DataContext="{Binding Source={StaticResource ViewModel}}"> tun. Gibt es einen Unterschied zwischen den beiden?

  2. Irgendwo sah ich ItemsSource="{StaticResource customers}" in einigem Beispiel. Wie ist ItemSource unterscheidet sich von DataContext. Während ich in dem Beispiel (1) sehen kann, habe ich das gleiche innerhalb der Bindung von DataContext (siehe hierzu: Source={StaticResource ViewModel} und in wird es durch customers ersetzt). Wie sind die zwei verschieden?

  3. Manchmal sehe ich auch direkt ItemsSource="{Binding Students}" gibt es keine StaticResource innerhalb. Wie unterscheidet es sich von StaticResource?

  4. Einige Beispiele haben einfach Binding="{Binding Name}".

  5. Wie unterscheiden sich SelectedItem und SelectedValue?

Könnte jemand bitte sie mit einem kleinen und einfachen Beispiel erklären? Auf Internet-Suche gibt es typische Beispiele für einen Anfänger zu verstehen.

Antwort

1

1) Technisch gesehen gibt es keinen Unterschied zwischen den beiden Erklärungen des Datenkontextes ich es in der Code-behind-tun, die wie folgt aussieht:

Partial Public Class MainPage 
    Inherits UserControl 

    Private _viewModel As TestViewModel 

    Public Sub New() 
     InitializeComponent() 
     _viewModel = TryCast(Resources("TheViewModel"), TestViewModel) 
     Me.DataContext = _viewModel 
    End Sub 
End Class 

2) Sie wollen nicht Um Ihre ItemsSource auf eine statische Seitenressource festzulegen, möchten Sie sie in Ihrem ViewModel auf eine Eigenschaft festlegen. Im Folgenden sehen Sie ein Beispiel für View and ViewModel, beachten Sie die Inherits and Impelments auf der VM. Dadurch kann Ihre VM Ihrer Ansicht mitteilen, dass sich Eigenschaften geändert haben, und die Eigenschaft neu laden.

Ausblick:

<UserControl x:Class="SilverlightTestApp.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" 
mc:Ignorable="d" 
d:DesignHeight="300" d:DesignWidth="400" 
xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation" 
xmlns:ModelViewModel="clr-namespace:SilverlightTestApp" > 

<UserControl.Resources> 
    <ModelViewModel:TestViewModel x:Key="TheViewModel" /> 
</UserControl.Resources> 

<Grid x:Name="LayoutRoot" Background="White" DataContext="{StaticResource TheViewModel}"> 
    <ItemsControl ItemsSource="{Binding SampleCollection}"> 
     <ItemsControl.ItemTemplate> 
      <DataTemplate> 
       <TextBlock Text="{Binding}"></TextBlock> 
      </DataTemplate> 
     </ItemsControl.ItemTemplate> 
    </ItemsControl> 
</Grid> 

Ansichtsmodell:

Imports System.ComponentModel 
Imports System.Collections.ObjectModel 
Public Class TestViewModel 
    Inherits DependencyObject 
    Implements System.ComponentModel.INotifyPropertyChanged 
    Implements INotifyDataErrorInfo 

    Private _model As TestModel 

    Sub New() 
     Me.New(New TestModel) 
    End Sub 

    Public Sub New(ByVal model As TestModel) 
     _model = model 

     _sampleCollection = New ObservableCollection(Of String) 
     _sampleCollection.Add("one") 
     _sampleCollection.Add("two") 
     _sampleCollection.Add("three") 
     _sampleCollection.Add("four") 

    End Sub 

    Private _sampleCollection As ObservableCollection(Of String) 
    Public Property SampleCollection As ObservableCollection(Of String) 
     Get 
      Return _sampleCollection 
     End Get 
     Set(value As ObservableCollection(Of String))    
      If value IsNot Nothing Then 
       _sampleCollection = value 
      End If 
      Me.OnPropertyChanged("SampleCollection") 

     End Set 
    End Property 

    Public Event PropertyChanged(sender As Object, e As PropertyChangedEventArgs) Implements INotifyPropertyChanged.PropertyChanged 

    Protected errors As New Dictionary(Of String, List(Of String)) 

    Protected Sub OnPropertyChanged(ByVal propertyName As String) 
     RaiseEvent PropertyChanged(Me, New System.ComponentModel.PropertyChangedEventArgs(propertyName)) 
    End Sub 

    ' #Region " Validation Plumbing" 
    ' Adds the specified error to the errors collection if it is not 
    ' already present, inserting it in the first position if isWarning is 
    ' false. Raises the ErrorsChanged event if the collection changes. 
    Public Sub AddError(ByVal propertyName As String, ByVal [error] As String, 
         ByVal isWarning As Boolean) 

     If Not errors.ContainsKey(propertyName) Then _ 
      errors(propertyName) = New List(Of String)() 

     If Not errors(propertyName).Contains([error]) Then 
      If isWarning Then 
       errors(propertyName).Add([error]) 
      Else 
       errors(propertyName).Insert(0, [error]) 
      End If 
      RaiseErrorsChanged(propertyName) 
     End If 

    End Sub 

    ' Removes the specified error from the errors collection if it is 
    ' present. Raises the ErrorsChanged event if the collection changes. 
    Public Sub RemoveError(ByVal propertyName As String, ByVal [error] As String) 

     If errors.ContainsKey(propertyName) AndAlso 
      errors(propertyName).Contains([error]) Then 

      errors(propertyName).Remove([error]) 
      If errors(propertyName).Count = 0 Then errors.Remove(propertyName) 
      RaiseErrorsChanged(propertyName) 

     End If 

    End Sub 
    Public Sub RemoveError(ByVal propertyName As String) 

     If errors.ContainsKey(propertyName) Then 

      errors.Remove(propertyName) 
      RaiseErrorsChanged(propertyName) 

     End If 

    End Sub 

    Public Sub RaiseErrorsChanged(ByVal propertyName As String) 
     OnPropertyChanged("HasErrors") 
     RaiseEvent ErrorsChanged(Me, 
      New DataErrorsChangedEventArgs(propertyName)) 
    End Sub 

    Public Event ErrorsChanged As EventHandler(Of DataErrorsChangedEventArgs) _ 
     Implements INotifyDataErrorInfo.ErrorsChanged 

    Public Function GetErrors(ByVal propertyName As String) _ 
     As System.Collections.IEnumerable _ 
     Implements INotifyDataErrorInfo.GetErrors 

     If (String.IsNullOrEmpty(propertyName) OrElse 
      Not errors.ContainsKey(propertyName)) Then Return Nothing 
     Return errors(propertyName) 

    End Function 

    Public ReadOnly Property HasErrors As Boolean _ 
     Implements INotifyDataErrorInfo.HasErrors 
     Get 
      Return errors.Count > 0 
     End Get 
    End Property 

End Class 

Das Kernstück oben ist Me.OnPropertyChanged("SampleCollection"), die die Ansicht erzählt die Eigenschaft zu aktualisieren es gebunden ist.

Ein Hinweis auf die Architektur, wenn Sie eine Anwendung mit mehreren Ansichten und Viewmodels bauen, eine ViewModelBase erstellen und es DependencyObject erben und INotifyPropertyChanged implementieren, dann alle Ihre reale Ansicht Modelle aus der ViewModelBase Inherit können.

Ich habe auch eine Klasse namens TestModel erstellt, die in der VM verwendet wird, aber es leer gelassen. Das Modell ist, wo Sie den Code, um mit der DB zu sprechen, oder was ich tue, rufen Sie einen WCF-Dienst, der mit meiner DB spricht.

5) Schließlich ist das SelectedItem das eigentliche Objekt innerhalb der ausgewählten ItemSource, während SelectedValue der Wert von SelectedValuePath ist. Im obigen Beispiel habe ich eine einfache Sammlung von String erstellt, aber Sie haben eine Sammlung von benutzerdefinierten Objekten mit mehreren Eigenschaften. Sie können den SelectedValuePath als eine dieser Eigenschaften angeben. Das SelectedItem würde das gesamte Objekt zurückgeben.

Verwandte Themen