用于绑定的xaml术语的差异

Sss*_*Sss 5 .net c# silverlight xaml mvvm

我是使用Silverlight的xaml(用于MVVM APPROACH)的初学者.我读了几篇文章,对此一点感到困惑.如果有人能解释以下之间的区别,我将非常感激.

假设我的XAML是:

  xmlns:viewmodel="clr-namespace:smallMVVM"
  ......
  ......  
 <UserControl.Resources>
        <viewmodel:ViewModel x:Key="ViewModel"/>
        <viewmodel:DatetimeToDateConverter x:Key="MyConverter"/>
 </UserControl.Resources>
Run Code Online (Sandbox Code Playgroud)

现在有什么区别:

  1. 我的意思是在MainPage.cs中,如果我这样做"this.DataContext = new ViewModel();".如果我执行以下操作,请在MainPage.xaml中<Grid DataContext="{Binding Source={StaticResource ViewModel}}">.这两者有什么区别吗?

  2. ItemsSource="{StaticResource customers}"在某些例子中我看到的地方.有什么ItemSource不同DataContext.虽然我可以在示例中(1)看到我在DataContext的Binding中有相同的内容(请参阅此内容:Source={StaticResource ViewModel}并将(2)其替换为customers).两者有何不同?

  3. 有时我也直接看到ItemsSource="{Binding Students}"里面没有StaticResource.它与StaticResource有何不同?

  4. 一些例子很简单Binding="{Binding Name}".

  5. 怎么样SelectedItemSelectedValue不同?

有人可以用一个简单的小例子解释一下吗?在互联网搜索中,有一些典型的例子供初学者理解.

Bri*_*ian 1

1)从技术上讲,数据上下文的两个声明之间没有区别,我喜欢在代码隐藏中执行此操作,如下所示:

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
Run Code Online (Sandbox Code Playgroud)

2)您不想将 ItemsSource 设置为静态页面资源,而是希望将其设置为 ViewModel 中的属性。下面是一个示例 View 和 ViewModel,请注意 VM 上的继承和实现,这些允许您的 VM 告诉您的 View 属性已更改,并重新加载属性。

看法:

<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>
Run Code Online (Sandbox Code Playgroud)

视图模型:

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
Run Code Online (Sandbox Code Playgroud)

上面的关键部分是Me.OnPropertyChanged("SampleCollection")告诉视图更新它绑定到的属性。

关于架构的注意事项,如果您正在构建具有多个View和ViewModel的应用程序,创建一个ViewModelBase并让它继承DependencyObject并实现INotifyPropertyChanged,那么您所有真实的视图模型都可以从ViewModelBase继承。

我还创建了一个在虚拟机中使用的名为 TestModel 的类,但将其留空。该模型是您放置与数据库对话的代码的地方,或者我所做的,调用与我的数据库对话的 WCF 服务。

5) 最后,SelectedItem 是选择的 ItemSource 中的实际对象,而 SelectedValue 是 SelectedValuePath 的值。在上面的示例中,我创建了一个简单的 String 集合,但假设您有一个具有多个属性的自定义对象的集合,您可以将 SelectedValuePath 指定为这些属性之一。SelectedItem 将返回整个对象。