【发布时间】:2012-03-02 10:00:50
【问题描述】:
我有一个用户控件,它显示位于绑定到视图模型的另一个页面内的地址。 viewmodel 有一个原始的 User,它有一个 Address 对象的集合。用户控件将驻留在多个页面上,因此我希望能够通过依赖属性将其绑定到地址列表。虽然我目前的解决方案正在工作,但它的某些地方感觉不对,我想我会征求第二意见。为了简洁起见,我已经删掉了很多代码。
基本上,页面绑定到 usercontrols 代码中的依赖属性,然后通过设置它的 itemsource 来更新 usercontrol 的数据网格。在我看来,这打破了 MVVM 的基本租户。
AddressListView 控件:
<UserControl x:Class="Insight.Controls.AddressListView"
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:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
xmlns:tk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit"
xmlns:command="clr-namespace:PrismFramework.Implementors.Commanding;assembly=PrismFramework"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="840">
<UserControl.Resources>
<command:ObservableCommand x:Name="EditAddressCommand" Value="{Binding EditAddressCmd}"/>
<command:ObservableCommand x:Name="DeleteAddressCommand" Value="{Binding DeleteAddressCmd}"/>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White">
<sdk:DataGrid Name="dgAddresses"
Height="Auto"
Width="Auto"
AutoGenerateColumns="False"
HeadersVisibility="None" >
<sdk:DataGrid.Columns>
<sdk:DataGridTemplateColumn x:Name="dgcAddresses"
Width="*" >
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Border x:Name="bdrAddress"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Height="Auto"
Width="Auto"
BorderBrush="Silver"
BorderThickness="1"
Padding="0"
Margin="1,1,1,1">
<Grid x:Name="grdAddressItem"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Height="Auto"
Width="Auto">
<Grid.RowDefinitions>
<RowDefinition Height="17" MinHeight="17"/>
<RowDefinition Height="17" MinHeight="17"/>
<RowDefinition Height="17" MinHeight="17"/>
<RowDefinition Height="17" MinHeight="17"/>
<RowDefinition Height="17" MinHeight="17"/>
<RowDefinition Height="17" MinHeight="17"/>
<RowDefinition Height="17" MinHeight="17"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="70"/>
<ColumnDefinition Width="55" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Padding="0,0,5,0" Text="Type:" TextAlignment="Right" />
<TextBlock Grid.Column="1" Padding="0" Text="{Binding Path=AType}" Grid.ColumnSpan="2" />
<TextBlock Grid.Row ="1" Grid.Column="0" Padding="0,0,5,0" Text="Address 1:" TextAlignment="Right" />
<!-- List Of Similar Fields ->
<Grid x:Name="grdAddressEditOptions"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Height="Auto"
Width="Auto"
Grid.Column="3"
Grid.RowSpan="7" >
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Button x:Name="btnEdit"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Height="Auto"
Width="Auto"
Grid.Row="0"
Padding="4,5,4,8"
Margin="0,8,10,0"
Command="{Binding Value, Source={StaticResource EditAddressCommand}}"
CommandParameter="{Binding}" >
<Button.Content>
<Image x:Name="btnEditIcon"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Height="Auto"
Width="Auto"
Source="/Insight.ModuleUser;component/Images/edit.png"
Visibility="Visible" />
</Button.Content>
</Button>
<Button x:Name="btnDelete"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Height="Auto"
Width="Auto"
Grid.Row="2"
Padding="4,5,4,8"
Margin="0,0,10,5"
Command="{Binding Value, Source={StaticResource DeleteAddressCommand}}"
CommandParameter="{Binding}" >
<Button.Content>
<Image x:Name="btnDeleteIcon"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Height="Auto"
Width="Auto"
Source="/Insight.ModuleUser;component/Images/delete.png"
Visibility="Visible" />
</Button.Content>
</Button>
</Grid>
</Grid>
</Border>
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
</sdk:DataGridTemplateColumn>
</sdk:DataGrid.Columns>
</sdk:DataGrid>
</Grid>
</UserControl>
AddressListView后面的代码:
Imports System.Collections.ObjectModel
Imports Insight.DataServices.Primitives
Partial Public Class AddressListView
Inherits UserControl
Public ReadOnly AddressesProperty As DependencyProperty = DependencyProperty.Register("Addresses", GetType(ObservableCollection(Of Address)), GetType(AddressListView), New PropertyMetadata(Nothing, New PropertyChangedCallback(AddressOf OnAddressesChanged)))
Public Sub New()
InitializeComponent()
End Sub
Public Property Addresses As ObservableCollection(Of Address)
Get
Return DirectCast(GetValue(AddressesProperty), ObservableCollection(Of Address))
End Get
Set(value As ObservableCollection(Of Address))
SetValue(AddressesProperty, value)
End Set
End Property
Public Sub OnAddressesChanged()
Me.dgAddresses.ItemsSource = Addresses
End Sub
End Class
基本页面:
<UserControl x:Class="Insight.ModuleUser.Views.EditUserView"
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:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
xmlns:prism="clr-namespace:Microsoft.Practices.Prism.Interactivity.InteractionRequest;assembly=Microsoft.Practices.Prism.Interactivity"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:cm="clr-namespace:System.ComponentModel;assembly=System.Windows"
xmlns:data="clr-namespace:System.Windows.Data;assembly=System.Windows"
xmlns:vm="clr-namespace:Insight.ModuleUser.ViewModels"
xmlns:command="clr-namespace:PrismFramework.Implementors.Commanding;assembly=PrismFramework"
xmlns:controls="clr-namespace:Insight.Controls;assembly=Insight.Controls"
xmlns:modalDialogs="clr-namespace:Insight.Controls.ModalDialogViews;assembly=Insight.Controls"
mc:Ignorable="d"
d:DesignHeight="500" d:DesignWidth="1144"
d:DataContext="{d:DesignData /Insight.ModuleUser;component/SampleData/EditUserViewModelSampleData.xaml}">
<UserControl.Resources>
<command:ObservableCommand x:Name="OpenProjectCommand" Value="{Binding OpenProjectCmd}"/>
<command:ObservableCommand x:Name="OpenPaymentCommand" Value="{Binding OpenPaymentCmd}"/>
<command:ObservableCommand x:Name="OpenInvoiceCommand" Value="{Binding OpenInvoiceCmd}"/>
<command:ObservableCommand x:Name="OpenPaymentItemCommand" Value="{Binding OpenPaymentItemCmd}"/>
<command:ObservableCommand x:Name="EditPhoneCommand" Value="{Binding EditPhoneNumberCmd}"/>
<command:ObservableCommand x:Name="DeletePhoneCommand" Value="{Binding DeletePhoneNumberCmd}"/>
<command:ObservableCommand x:Name="EditEmailAddressCommand" Value="{Binding EditEmailAddressCmd}"/>
<command:ObservableCommand x:Name="DeleteEmailAddressCommand" Value="{Binding DeleteEmailAddressCmd}"/>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" >
<controls:AddressListView x:Name="ctrlAddressListView"
Addresses="{Binding User.Addresses}" />
</Grid>
</UserControl>
【问题讨论】:
标签: silverlight mvvm user-controls dependency-properties