2012-02-09 26 views
0

私はビューモデルにバインドされている別のページの内部に格納されているアドレスを表示するユーザーコントロールを持っています。ビューモデルは、のユーザのコレクションを持ち、アドレスのオブジェクトを持っています。ユーザーコントロールはいくつかのページにありますので、依存関係プロパティを介してアドレス一覧にバインドできるようにしたいと考えています。私の現在の解決策は機能していますが、それについては何か正しいとは思えません。私は第二の意見を求めたいと思いました。私は簡潔にするために多くのコードを整理しました。MVVM + UserControl + UserControl + DependencyProperty

基本的に、このページはusercontrolsコードの依存関係プロパティにバインドされ、そのコントロールのitemourceを設定してusercontrolのDataGridを更新します。これは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> 

答えて

1

これは完全に合理的なアプローチです。ただし、コード内のアイテムソースを設定するのではなく、ユーザーコントロールビューでバインディングを使用できます。

これを行うには、ユーザーコントロールのDataContextをユーザーコントロールの種類に設定する必要があります。これは、ユーザーコントロール(this.DataContext = thisを設定する)ために、またはXAMLでバインディング要素のいずれかを介してコードで背後に行うことができる:

<UserControl 
... 
x:Name="MyName" 
DataContext="{Binding ElementName=MyName}" 

しかし、私のアプローチは、すべてのあなたのように、すべてでユーザーコントロールを使用するのではないだろう実際には、ビューの構図と他のビュー間のビューの特定のセクションの再利用について話しています。

ビュー構成は、Caliburn.MicroなどのMVVMフレームワークでは非常に簡単です。この場合、あなたはAddressViewModelAddressViewを持ち、ベースビューにAddressViewを注入するContentControlを使用します。

<ContentControl x:Name="AddressViewModel" /> 
+0

私はこの1つは非常に単純であることに同意します。私がDependencyPropertiesに精通していないので、私はヒップから撮影するのではなく、ベストプラクティスのアプローチを使用していることを確認したかったのです。私が足で自分を撃っていることを後で発見した。 :) –

関連する問題