簡體   English   中英

Silverlight中的類型化數據模板

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM