2015-11-29 96 views
0

所以我有一個TabControl,每個選項卡都有一個ViewModel1的實例。 ViewModel1的View有一個我自己構建的自定義UserControl,它基本上公開了一個DependencyProperty「Images」,用於存儲控件所具有的圖像列表。此屬性已綁定到ViewModel1的屬性「Images」(OneWayToSource)。WPF MVVM - 由於某種原因在ViewModel之間共享的集合

我遇到的問題是,由於某種原因,ViewModel1(所有標籤)的所有實例都共享此屬性。因此,如果Tab1在控件中有1個圖像,而Tab2在控件中有3個圖像,則每個ViewModel1實例的「Images」屬性具有4個圖像的集合。

我不知道這會發生什麼 - 任何人有任何想法?

請注意,我使用Caliburn.Micro作爲MVVM框架。

編輯:控制內的財產的定義是這樣的:

public List<ImageData> Images 
    { 
     get { return (List<ImageData>)GetValue(ImagesProperty); } 
     set { return; } 
    } 

    public static readonly DependencyProperty ImagesProperty = 
     DependencyProperty.Register("Images", typeof(List<ImageData>), typeof(WebImageAlbum), 
      new UIPropertyMetadata(new List<ImageData>())); 

新項目剛剛添加到與Images.Add()和視圖的XAML中,這個屬性被綁定到視圖模型的「圖像「屬性與模式= OneWayToSource。

編輯:這是與用戶控件的選項卡視圖的樣子:

<UserControl 
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:local="clr-namespace:NET_MD3.Views" 
xmlns:cal="http://www.caliburnproject.org" 
xmlns:CustomControls="clr-namespace:NET_MD3.CustomControls" x:Class="NET_MD3.Views.AlbumTabView" 
mc:Ignorable="d" 
d:DesignHeight="267.789" d:DesignWidth="473.684"> 
<Grid> 
    <CustomControls:WebImageAlbum x:Name="Album" Margin="10,10,10,50" Width="Auto" Height="Auto" ImageWidthHeight="95" 
     cal:Message.Attach="[Event ImageClicked] = [Action ImageClicked($eventArgs)]" 
     Images="{Binding Images, Mode=OneWayToSource}"/> 
    <Button x:Name="CloseTab" Content="Close tab and delete album" HorizontalAlignment="Left" Margin="10,0,0,10" VerticalAlignment="Bottom" Width="172" Height="30"/> 
    <Button x:Name="button" Content="Button" HorizontalAlignment="Left" Margin="342,243,0,0" VerticalAlignment="Top" Width="75" Click="button_Click"/> 
</Grid> 

這是視圖模型的樣子:

public class AlbumTabViewModel : Screen, IAlbumTabItem 
{ 
    #region Constructor 

    public AlbumTabViewModel(int id) 
    { 
     this.TabID = id; 
    } 

    #endregion 

    #region Properties 

    /// <summary> 
    /// Get the Images loaded in this tab's Album (do not use the setter - it's for the Binding only) 
    /// </summary> 
    public List<ImageData> Images 
    { 
     get; set; 
    } 

    /// <summary> 
    /// The Display name of this Screen (Tab) 
    /// </summary> 
    public override string DisplayName 
    { 
     get 
     { 
      return $"Album #{this.TabID}"; 
     } 
     set { base.DisplayName = value; } 
    } 

    /// <summary> 
    /// The ID of this tab 
    /// </summary> 
    public int TabID { get; private set; } 

    #endregion 

    #region Actions 

    /// <summary> 
    /// Delete this album tab 
    /// </summary> 
    public void CloseTab() 
    { 
     this.TryClose(); 
    } 


    /// <summary> 
    /// An image has been clicked within the album 
    /// </summary> 
    /// <param name="e"></param> 
    public void ImageClicked(ImageData e) 
    { 
     //ttt 
    } 

    #endregion 
} 
+1

我的心理調試器說你有一個靜態列表。沒有我能做的最好的代碼。 –

+0

總共有很多代碼(View,ViewModel,Custom Control),所以很難說我應該放什麼。不過,我已經添加了「Images」依賴項屬性的聲明,因此您可以看一下(它不是靜態的)。 – Fabis

+1

爲什麼你把它作爲一個DependencyProperty而不是簡單地綁定? –

回答

0

原來,問題是在DependencyProperty的聲明中。在我傳遞給屬性的靜態聲明的UIPropertyMetadata()中,我使用'new List()'作爲默認值,結果你不能這樣做,因爲它會將該List創建爲一個靜態對象,這解釋了爲什麼UserControl的每個實例都有相同的列表。這可能是因爲DependencyProperty本身是靜態的,所以當它試圖創建該默認值時,它也是靜態的。

我猜這個教訓是,在聲明一個新的DependencyProperty時,不要將引用類型設置爲默認值,如果必須的話,可以將它設置在別的地方(在訪問該值的CLR屬性內)。

相關問題