首页 文章

用于绑定的xaml术语的差异

提问于
浏览
5

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

假设我的XAML是:

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

现在有什么区别:

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

  • 在某个例子中,我看到 ItemsSource="{StaticResource customers}" . ItemSourceDataContext 的区别如何?虽然我在示例 (1) 中可以看到我在DataContext的Binding中有相同的内容(请参阅: Source={StaticResource ViewModel} 并在 (2) 中将其替换为 customers ) . 两者有何不同?

  • 有时我也直接看到 ItemsSource="{Binding Students}" 里面没有 StaticResource . 它与StaticResource的不同之处是什么?

  • 一些例子只是 Binding="{Binding Name}" .

  • SelectedItemSelectedValue 如何不同?

Could someone please explain them with a small and simple example ? 在互联网搜索中,有一些典型的例子供初学者理解 .

1 回答

  • 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
    

    2)您不希望将ItemsSource设置为静态页面资源,您希望将其设置为ViewModel中的属性 . 下面是一个示例View和ViewModel,注意VM上的继承和Impelments,这些允许您的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>
    

    视图模型:

    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
    

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

    关于体系结构的说明,如果要构建具有多个View和ViewModel的应用程序,则创建ViewModelBase并使其继承DependencyObject并实现INotifyPropertyChanged,然后所有实际视图模型都可以从ViewModelBase继承 .

    我还创建了一个名为TestModel的类,它在VM中使用,但保留为空 . 该模型是您将代码与数据库进行通信的地方,或者我所做的,调用与我的数据库通信的WCF服务 .

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

相关问题