[英]Typed Data Templates in Silverlight
我的理解是Silverlight不支持帶有DataType屬性的DataTemplates。
然后,您將如何在SL中完成以下任務(作者是Josh Smith,下面是完整鏈接)。 簡而言之,他是說,如果將TabControl的選項卡頁綁定到ViewModels的集合,WPF將通過查找具有適當(匹配)DataType集的DataTemplate找出如何動態顯示每個頁面。 太酷了,但是我想知道您將如何在Silverlight中做到這一點。
將視圖應用於ViewModel
MainWindowViewModel間接在主窗口的TabControl中添加和從其中刪除WorkspaceViewModel對象。 通過依賴數據綁定,TabItem的Content屬性將接收ViewModelBase派生的對象以顯示。 ViewModelBase不是UI元素,因此它不具有渲染本身的固有支持。 默認情況下,在WPF中,通過在TextBlock中顯示對其ToString方法的調用結果來呈現非可視對象。 顯然,這不是您所需要的,除非您的用戶迫切希望查看我們的ViewModel類的類型名稱!
您可以輕松地告訴WPF如何使用鍵入的DataTemplates呈現ViewModel對象。 類型化的DataTemplate沒有分配x:Key值,但確實將其DataType屬性設置為Type類的實例。 如果WPF嘗試呈現您的ViewModel對象之一,它將檢查資源系統在范圍內是否有類型化的DataTemplate,其DataType與ViewModel對象的類型相同(或作為其基本類)。 如果找到一個,它將使用該模板來呈現選項卡項的Content屬性引用的ViewModel對象。
MainWindowResources.xaml文件具有ResourceDictionary。 該字典將添加到主窗口的資源層次結構中,這意味着它包含的資源在窗口的資源范圍內。 當選項卡項的內容設置為ViewModel對象時,該詞典中鍵入的DataTemplate將提供一個視圖(即用戶控件)來呈現它,如圖10中的圖10所示。
圖10中的http://msdn.microsoft.com/zh-cn/magazine/dd419663.aspx 。
這是您可以做到的一種方法。 過去,我曾使用過類似的技術,並且在此方面取得了巨大的成功。
考慮一個非常簡單的容器,它將像這樣為您創建視圖:
public class ViewMapper : ContentControl
{
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
{
base.OnPropertyChanged(e);
if (e.Property.Name == "DataContext")
WhenDataContextChanges();
}
private void WhenDataContextChanges()
{
if (DataContext == null)
Content = null;
else
Content = ViewFactory.GetView(DataContext.GetType());
}
}
編輯
因此,您可以使用此控件為您執行映射:
<Border DataContext="{Binding MyViewModel}">
<ViewMapper />
</Border>
結束編輯
請注意, ViewMapper
只是等待數據上下文更改,為數據類型查找適當的視圖,然后創建一個新的視圖。 它依賴於ViewFactory,這是一個非常簡單的靜態查找,可將類型映射到視圖:
public class ViewFactory
{
private static readonly Dictionary<string, Func<UIElement>> _registry = new Dictionary<string, Func<UIElement>>();
private static string Key(Type viewModelType)
{
return viewModelType.FullName;
}
public static void RegisterView(Type viewModelType, Func<UIElement> createView)
{
_registry.Add(Key(viewModelType), createView);
}
public static UIElement GetView(Type viewModelType)
{
var key = Key(viewModelType);
if (!_registry.ContainsKey(key))
return null;
return _registry[key]();
}
}
然后,您只需要在某個位置注冊視圖映射:
ViewFactory.RegisterView(typeof(SomeViewModel), () => new SomeView());
請注意,ViewFactory可以輕松使用Activator.CreateInstance
而不是使用Func機制。 更進一步,您可以使用IoC容器...您始終可以決定通過ViewModel上的字符串Name屬性(而不是類型)進行映射...這里的可能性是無限而強大的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.