簡體   English   中英

如何將UserControl的DependencyProperty綁定到MVVM的ViewModel中的屬性?

[英]How to bind a DependencyProperty of a UserControl to a property in it's ViewModel in MVVM?

問題不在於如何使這些東西正常工作,它已經可以了。 這是關於我正在經歷的一些奇怪行為,我需要了解它。 我有一個包含一些樣式的ResourceDictionary ,其中一種樣式為TargetType="{x:Type UserControl}"x:Key="UCStyle" ; 將其應用於項目中的多個UserControl 這些UserControl的其中一些在其ViewModel中具有string State屬性,可用於應用視覺狀態(通過外部類和附加屬性,綁定到XAML中的ViewModel)。 到現在為止一切都非常完美,然后,我嘗試將DependencyProperty State添加到UserControl ,然后將其綁定到ViewModel中的state屬性,我的嘗試是:

<UserControl.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <!--ResourceDictionary Source="..."/-->
        </ResourceDictionary.MergedDictionaries>
        <Style x:Key="MyStyle" TargetType="{x:Type local:MyUserControl}" BasedOn="{StaticResource UCStyle}">
            <Setter Property="State" Value="{Binding State, Mode=TwoWay}"/>
        </Style>
    </ResourceDictionary>
</UserControl.Resources>
<UserControl.Style>
    <DynamicResourceExtension ResourceKey="MyStyle" />
</UserControl.Style>

這在運行時完美運行,但是在設計時,總是強調這些行 'MyUserControl'TargetType與元素'UserControl'的類型不匹配。

並顯示錯誤提示:

'MyUserControl'TargetType與元素'UserControl'的類型不匹配。

而且不適既不UCStyle也不MyStyle在XAML瀏覽器在Visual Studio中,甚至不畫小孩UserControl s請正確。 我沒想到解決方案可以正常運行,但是確實可以!

現在我的問題是:

  • 為什么它在正常運行時在設計時顯示這些錯誤?
  • 如何在設計時擺脫這些錯誤? (我清理並重新構建了解決方案,然后重新啟動了Visual Studio,但這些都不起作用)
  • MVVM中,在這種情況下處理“ UserControl”可視狀態的最佳實踐是什么?
  • 將UserControl的DependencyProperty綁定到MVVM的ViewModel中的屬性的最佳實踐是什么?

我正在使用Visual Studio 2012。

WPF設計器在設計時顯示偽造的錯誤是有害的。 您不能做很多事,但是請忽略它們。

視覺狀態是UI的關注點,因此應包含在UI中。 MVVM 並不意味着沒有代碼隱藏。 將您的代碼隱藏用於UI任務,並將業務邏輯放入視圖模型中。

您的問題表明您正在創建自定義視圖模型,以保留用戶控件的視圖邏輯。 說真的,不要那樣做。 那會給您帶來麻煩。 它會干擾數據綁定的設計工作方式。

沒有將用戶控制元素綁定到其表面上定義的屬性的“最佳實踐”。 這取決於。 但是,使用樣式執行此操作似乎很奇怪。 您可以簡單地為UserControl的根賦予x:Name="root" ,然后在綁定中使用ElementName=root

在UserControl中綁定到UserControl上定義的屬性示例(取自舊的原型)...

這是一個旨在添加或刪除內容列表的UserControl。

  • 在UserControl上定義的DependencyProperties
  • UserControl中綁定到這些屬性的綁定

我不保證這項工作有效,但可以說明如何完成:

public partial class ItemsEditor : UserControl
{
    #region Items
    public static readonly DependencyProperty ItemsProperty =
        DependencyProperty.Register(
            "Items",
            typeof(IEnumerable<Item>),
            typeof(ItemsEditor),
            new UIPropertyMetadata(null));
    public IEnumerable<Item> Items
    {
        get { return (IEnumerable<Item>)GetValue(ItemsProperty); }
        set { SetValue(ItemsProperty, value); }
    }
    #endregion  
    #region AddItem
    public static readonly DependencyProperty AddItemProperty =
        DependencyProperty.Register(
            "AddItem",
            typeof(ICommand),
            typeof(ItemsEditor),
            new UIPropertyMetadata(null));
    public ICommand AddItem
    {
        get { return (ICommand)GetValue(AddItemProperty); }
        set { SetValue(AddItemProperty, value); }
    }
    #endregion          
    #region RemoveItem
    public static readonly DependencyProperty RemoveItemProperty =
        DependencyProperty.Register(
            "RemoveItem",
            typeof(ICommand),
            typeof(ItemsEditor),
            new UIPropertyMetadata(null));
    public ICommand RemoveItem
    {
        get { return (ICommand)GetValue(RemoveItemProperty); }
        set { SetValue(RemoveItemProperty, value); }
    }        
    #endregion  
    public ItemsEditor()
    {
        InitializeComponent();
    }
}

它僅列出了一堆東西,您可以添加新東西或從列表中刪除東西。 這是xaml中的綁定

<UserControl x:Class="LolPrototype.ItemsEditor"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:t="clr-namespace:UCsAndICommands"
             x:Name="root">
    <UserControl.Resources>
        <DataTemplate DataType="{x:Type t:Item}">
            <StackPanel Orientation="Horizontal">
                <Button Command="{Binding RemoveItem, ElementName=root}"
                        CommandParameter="{Binding}">Remove</Button>
                <TextBox Text="{Binding Name}" Width="100"/>
            </StackPanel>
        </DataTemplate>
    </UserControl.Resources>
    <StackPanel>
        <Button Command="{Binding AddItem, ElementName=root}">Add</Button>
        <ItemsControl ItemsSource="{Binding Items, ElementName=root}" />
    </StackPanel>
</UserControl>

顯然,您可以在祖先資源的列表之外定義DataTemplates。 關鍵是要顯示如何使用ElementName綁定來綁定UserControl中定義的屬性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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