您希望UI元素具有良好的設計時體驗(包括在Blend中)。這聽起來像是一個合理的目標。
讓我們來看看UI元素是什麼。對於這個答案的其餘部分,我將稱之爲控制。控件的責任是呈現UI並響應用戶事件。只要它應該具有行爲,它應該只具有與UI渲染和用戶事件相關的行爲。除此之外,框架本身(Silverlight以及WPF)強加一條規則:所有控件都必須具有默認構造函數。此外,由於DataContext
是屬性,因此可以將其分配。
我們應該牢記封裝。我們開發的任何控制應該在上面給出的約束內很好地工作。這意味着,除了具有默認構造函數外,也應該在沒有DataContext的情況下正常工作。換句話說,Blendability的體驗應該由Control本身提供,而不是任何需要引導的外部容器來指定DataContext
。
當控件必須響應用戶事件時,我總是發現接口綽綽有餘。將ICommands
附加到控件中的任何適用的事件處理程序。 ICommands
由視圖模型定義,但ICommand
的美妙之處在於它基本上是一種無效的方法,這意味着在DataContext
爲空的情況下提供(無操作)本地默認值是微不足道的。然而,這並不是必須的,因爲命令不是由設計者調用的。
下面是my book一個例子:
<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();
}
}
雖然這是一個偉大的,正確的答案 - 我使用的技術自己 - 我認爲這是用代碼短小的代碼解釋你的意思更詳細,或者指向完成的地方。 –
如何顯示*缺少代碼? –
雖然這很好,但提供設計時數據的重點在於,控件在設計器中的渲染方式與在運行時顯示的方式相似。這允許設計師以更準確的方式提供樣式作爲網格,例如,將具有在運行時呈現的行。沒有設計時數據,網格將呈現,列將出現,但不會有數據(人,沒有行)。這不僅會影響設計控件,還會影響UI元素基於其內容流動的佈局。不過,我很欣賞這種詳細的迴應。 – SonOfPirate