2014-07-10 17 views
5

Sono un principiante con xaml (per MVVM APPROACH) che utilizza Silverlight. Ho letto diversi documenti e sono un po 'confuso su tutto. Apprezzerei molto se qualcuno potesse spiegare la differenza tra quanto segue.Differenza nei termini xaml utilizzati per il binding

Suppongo che la mia XAML è:

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

Ora, qual è la differenza tra:

  1. intendo in MainPage.cs se faccio "this.DataContext = new ViewModel();". E in MainPage.xaml se faccio il seguente <Grid DataContext="{Binding Source={StaticResource ViewModel}}">. C'è qualche differenza tra i due?

  2. Da qualche parte ho visto ItemsSource="{StaticResource customers}" in qualche esempio. In che modo ItemSource è diverso da DataContext. Considerando che posso vedere nell'esempio (1) che ho lo stesso all'interno del Binding di DataContext (vedere questo: Source={StaticResource ViewModel} e in (2) è sostituito con customers). Come sono i due diversi?

  3. A volte vedo anche ItemsSource="{Binding Students}" non c'è StaticResource all'interno. In che modo è diverso da StaticResource?

  4. Alcuni esempi sono semplicemente Binding="{Binding Name}".

  5. In che modo differiscono SelectedItem e SelectedValue?

Qualcuno potrebbe spiegare loro con un piccolo e semplice esempio? Nella ricerca su Internet ci sono esempi tipici per un principiante da capire.

risposta

1

1) Tecnicamente non v'è alcuna differenza tra le due dichiarazioni del contesto dati mi piace fare nel code-behind, che assomiglia a questo:

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) Non vuoi per impostare la risorsa ItemsSource su una risorsa della pagina statica, si desidera impostarla su una proprietà nel ViewModel. Di seguito è riportato un esempio di View e ViewModel, si noti l'Eredita e gli Impulsi sulla VM, Questi consentono alla tua VM di dire alla tua vista che le proprietà sono cambiate e di ricaricare la proprietà.

Vista:

<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> 

ViewModel:

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 

Il pezzo chiave di cui sopra è Me.OnPropertyChanged("SampleCollection") che racconta la vista per aggiornare la proprietà è destinato a.

Una nota su architettura, se si sta costruendo un programma con più viste e ViewModels, creare un ViewModelBase e lo hanno ereditare DependencyObject e implementare INotifyPropertyChanged, poi tutti i modelli vista reali possono ereditare dal ViewModelBase.

Ho anche creato una classe denominata TestModel utilizzata nella VM, ma lasciata vuota. Il modello è il punto in cui si inserisce il codice per comunicare con il DB, o cosa faccio, chiamare un servizio WCF che comunica con il mio DB.

5) Infine, l'oggetto SelectedItem è l'oggetto effettivo all'interno di ItemSource selezionato, mentre SelectedValue è il valore di SelectedValuePath. Nell'esempio sopra, ho creato una semplice raccolta di String, ma diciamo che hai una raccolta di oggetti personalizzati che hanno più proprietà, puoi specificare SelectedValuePath come una di quelle proprietà. Il SelectedItem restituirebbe l'intero oggetto.

Problemi correlati