所以我有一个TabControl,它有一个ViewModel1实例作为每个标签。 ViewModel1的View有一个自定义的UserControl我构建,基本上暴露了DependencyProperty" Images"存储控件具有的图像列表。此属性已绑定(OneWayToSource)到ViewModel1的属性" Images"。
我遇到的问题是,由于某种原因,ViewModel1(所有标签)的所有实例都在共享此属性。因此,如果Tab1在控件中有1个图像,而Tab2在控件中有3个图像,那么"图像"每个ViewModel1实例的属性都有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()添加新项目,并且在View的XAML中,此属性绑定到ViewModel&#34;图像&#34; Mode = OneWayToSource的属性。
编辑:这是UserControl的Tab视图:
<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>
这就是ViewModel的样子:
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
}
答案 0 :(得分:0)
结果证明问题出在DependencyProperty的声明中。在我传递给属性的静态声明的UIPropertyMetadata()中,我使用了一个'new List()'作为默认值,结果证明你不能真正做到这一点,因为它会将List创建为一个静态对象,它解释了为什么UserControl的每个实例都有相同的列表。这可能是因为DependencyProperty本身是静态的,因此当它尝试创建该默认值时,它也将是静态的。
我猜教训是在声明新的DependencyProperty时不要将引用类型作为默认值,如果必须,请将其设置在别处(在访问值的CLR属性中,或其他内容)。