UI要素に優れた設計時エクスペリエンス(Blendを含む)を持たせる必要があります。それは合理的な目標のように聞こえます。
UI要素とは何かを見てみましょう。この回答の残りの部分では、これをコントロールと呼びます。コントロールの役割は、UIをレンダリングし、ユーザーイベントに応答することです。動作が必要な限り、UIレンダリングとユーザーイベントに関連する動作のみが必要です。
これに加えて、フレームワーク自体(SilverlightおよびWPF)はルールを課します。すべてのコントロールにはデフォルトのコンストラクターが必要です。さらに、DataContext
はプロパティであるため、割り当てるのはオプションです。
カプセル化を念頭に置く必要があります。私たちが開発するコントロールは、上記の制約内でうまく機能するはずです。これは、デフォルトのコンストラクターがあることは別として、DataContextがなくても正しく機能するはずであることを意味します。つまり、Blendabilityエクスペリエンスは、を割り当てるためにブートストラップする必要のある外部コンテナーではなく、コントロール自体によって提供される必要がありますDataContext
。
コントロールがユーザーイベントに応答する必要がある場合、私は常にICommand
インターフェイスが十分すぎると感じています。ICommands
コントロール内の該当するイベントハンドラーにアタッチします。はICommands
ビューモデルによって定義されますが、の利点は、基本的にvoidメソッドであるということです。つまり、がnullICommand
の場合に(no-op)ローカルデフォルトを指定するのは簡単です。DataContext
ただし、コマンドは設計者によって呼び出されないため、これが必要になることはめったにありません。
これが私の本の例です:
<Window x:Class="Ploeh.Samples.ProductManagement.WpfClient.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Product Management"
Height="300"
Width="300"
MinHeight="300"
MinWidth="300">
<Window.Resources>
<Style x:Key="ProductStyle" TargetType="{x:Type ListViewItem}">
<Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=TwoWay}" />
</Style>
</Window.Resources>
<DockPanel FocusManager.FocusedElement="{Binding ElementName=productsListView}">
<Menu DockPanel.Dock="Top">
<MenuItem Header="_File">
<Separator />
<MenuItem Header="E_xit" Command="{Binding Path=CloseCommand}" />
</MenuItem>
<MenuItem Header="_Actions">
<MenuItem Header="_Refresh" InputGestureText="F5" Command="{Binding Path=RefreshCommand}" />
<MenuItem Header="_Add Product" InputGestureText="Ins" Command="{Binding Path=InsertProductCommand}" />
<MenuItem Header="_Edit Product" InputGestureText="Enter" Command="{Binding Path=EditProductCommand}" />
<MenuItem Header="_Delete Product" InputGestureText="Del" Command="{Binding Path=DeleteProductCommand}" />
</MenuItem>
</Menu>
<ToolBarTray DockPanel.Dock="Top" HorizontalAlignment="Stretch">
<ToolBar HorizontalAlignment="Stretch" HorizontalContentAlignment="Left">
<Button Command="{Binding Path=RefreshCommand}">Refresh</Button>
<Button Command="{Binding Path=InsertProductCommand}">Add</Button>
<Button Command="{Binding Path=EditProductCommand}">Edit</Button>
<Button Command="{Binding Path=DeleteProductCommand}">Delete</Button>
</ToolBar>
</ToolBarTray>
<ListView x:Name="productsListView" ItemContainerStyle="{StaticResource ProductStyle}" ItemsSource="{Binding Path=Products}" SelectionMode="Single">
<ListView.View>
<GridView>
<GridViewColumn Header="Id" DisplayMemberBinding="{Binding Path=Id}" />
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding Path=Name}" />
<GridViewColumn Header="Price" DisplayMemberBinding="{Binding Path=UnitPrice}" />
</GridView>
</ListView.View>
</ListView>
</DockPanel>
</Window>
およびコードビハインド:
public partial class MainWindow : Window
{
public MainWindow()
{
this.InitializeComponent();
}
}