【发布时间】:2015-11-29 02:09:18
【问题描述】:
所以我有一个 TabControl,每个选项卡都有一个 ViewModel1 实例。 ViewModel1 的 View 有一个我构建的自定义 UserControl,它基本上公开了一个 DependencyProperty “Images”,它存储了控件所具有的图像列表。此属性已绑定 (OneWayToSource) 到 ViewModel1 的属性“Images”。
我遇到的问题是,由于某种原因,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() 添加到该项目中,并且在 View 的 XAML 中,此属性通过 Mode=OneWayToSource 绑定到 ViewModel 的“Images”属性。
编辑:这是带有 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
}
【问题讨论】:
-
我的心理调试器说你有一个静态列表。没有我能做的最好的代码。
-
总共有很多代码(视图、视图模型、自定义控件),所以很难说我应该放什么。不过,我已经添加了“Images”依赖属性的声明,所以你可以看一下(它不是静态的)。
-
你为什么把它设为 DependencyProperty 而不是简单地绑定?
-
@Fabis ViewModel 的代码,更新列表的代码,至少是 XAML
-
我将其设为 DependencyProperty,因此我可以通过 XAML 绑定到它,我不想在代码隐藏中做任何事情。
标签: wpf mvvm caliburn.micro