我面临一个奇怪的问题。我在 XAML 程序中创建了两个用作 ViewModel 的类。这两个类非常相似,但其中之一不会将“属性更改”事件传递给 UI。在这两种情况下,我都使用 binding TwoWay
。我尝试在同一个 UI 中为另一个类更改一个类并MovieGroup
最终工作,但不是MovieDataItem
(意味着绑定的 XAML 声明被证明是有效的)
以下是课程:
public class MovieDataItem : DependencyObject
{
public MovieDataItem(String uniqueId, String title, String subtitle, String imagePath, String description, String content)
{
this.UniqueId = uniqueId;
this.Title = title;
this.Subtitle = subtitle;
this.Description = description;
this.ImagePath = imagePath;
this.Content = content;
}
public MovieDataItem(MovieDataItem other)
{
UniqueId = other.UniqueId;
Title = other.Title;
Subtitle = other.Subtitle;
Description = other.Description;
ImagePath = other.ImagePath;
Content = other.Content;
}
public string UniqueId { get; set; }
public String Title
{
get { return (String)this.GetValue(TitleProperty); }
set { this.SetValue(TitleProperty, value); }
}
public static readonly DependencyProperty TitleProperty = DependencyProperty.Register(
"Title", typeof(String), typeof(MovieDataItem), new PropertyMetadata(false));
public String Subtitle
{
get { return (String)this.GetValue(SubtitleProperty); }
set { this.SetValue(SubtitleProperty, value); }
}
public static readonly DependencyProperty SubtitleProperty = DependencyProperty.Register(
"Subtitle", typeof(String), typeof(MovieDataItem), new PropertyMetadata(false));
public String Description
{
get { return (String)this.GetValue(DescriptionProperty); }
set { this.SetValue(DescriptionProperty, value); }
}
public static readonly DependencyProperty DescriptionProperty = DependencyProperty.Register(
"Description", typeof(String), typeof(MovieDataItem), new PropertyMetadata(false));
public String Content
{
get { return (String)this.GetValue(ContentProperty); }
set { this.SetValue(ContentProperty, value); }
}
public static readonly DependencyProperty ContentProperty = DependencyProperty.Register(
"Content", typeof(String), typeof(MovieDataItem), new PropertyMetadata(false));
public String ImagePath
{
get { return (String)this.GetValue(ImagePathProperty); }
set { this.SetValue(ImagePathProperty, value); }
}
public static readonly DependencyProperty ImagePathProperty = DependencyProperty.Register(
"ImagePath", typeof(String), typeof(MovieDataItem), new PropertyMetadata(false));
public override string ToString()
{
return this.Title;
}
public void CopyTo(MovieDataItem other)
{
other.UniqueId = UniqueId;
other.Title = Title;
other.Subtitle = Subtitle;
other.Description = Description;
other.ImagePath = ImagePath;
other.Content = Content;
}
}
/// <summary>
/// Generic group data model.
/// </summary>
public class MovieGroup : DependencyObject
{
public MovieGroup(String uniqueId, String title, String subtitle, String imagePath, String description)
{
this.UniqueId = uniqueId;
this.Title = title;
this.Subtitle = subtitle;
this.Description = description;
this.ImagePath = imagePath;
this.Items = new ObservableCollection<MovieDataItem>();
}
public MovieGroup(MovieGroup other)
{
UniqueId = other.UniqueId;
Title = other.Title;
Subtitle = other.Subtitle;
Description = other.Description;
ImagePath = other.ImagePath;
Items = other.Items;
}
public string UniqueId { get; set; }
public ObservableCollection<MovieDataItem> Items
{
get { return (ObservableCollection<MovieDataItem>)this.GetValue(ItemsProperty); }
set { this.SetValue(ItemsProperty, value); }
}
public static readonly DependencyProperty ItemsProperty = DependencyProperty.Register(
"Items", typeof(ObservableCollection<MovieDataItem>), typeof(MovieGroup), new PropertyMetadata(false));
public String Title
{
get { return (String)this.GetValue(TitleProperty); }
set { this.SetValue(TitleProperty, value); }
}
public static readonly DependencyProperty TitleProperty = DependencyProperty.Register(
"Title", typeof(String), typeof(MovieGroup), new PropertyMetadata(false));
public String Subtitle
{
get { return (String)this.GetValue(SubtitleProperty); }
set { this.SetValue(SubtitleProperty, value); }
}
public static readonly DependencyProperty SubtitleProperty = DependencyProperty.Register(
"Subtitle", typeof(String), typeof(MovieGroup), new PropertyMetadata(false));
public String Description
{
get { return (String)this.GetValue(DescriptionProperty); }
set { this.SetValue(DescriptionProperty, value); }
}
public static readonly DependencyProperty DescriptionProperty = DependencyProperty.Register(
"Description", typeof(String), typeof(MovieGroup), new PropertyMetadata(false));
public String ImagePath
{
get { return (String)this.GetValue(ImagePathProperty); }
set { this.SetValue(ImagePathProperty, value); }
}
public static readonly DependencyProperty ImagePathProperty = DependencyProperty.Register(
"ImagePath", typeof(String), typeof(MovieGroup), new PropertyMetadata(false));
public override string ToString()
{
return this.Title;
}
public void CopyTo(MovieGroup other)
{
other.UniqueId = UniqueId;
other.Title = Title;
other.Subtitle = Subtitle;
other.Description = Description;
other.ImagePath = ImagePath;
other.Items = Items;
}
}
附加信息:
DataContext
设置如下:
DataContext="{Binding DefaultViewModel, RelativeSource={RelativeSource Self}}"
对象如下:
ObservableDictionary defaultViewModel = new ObservableDictionary();
然后,我将我的电影组和项目添加到字典中。出于测试目的,我只使用了一种 xaml 表单并在两个对象之间交替(它们具有我可以使用的通用属性名称)。它是这样的:
//C#; Adding Group to the dictionary
MovieGroup group = new MovieGroup(Guid.NewGuid().ToString(), "My Category", String.Empty, String.Empty, "Description");
DefaultViewModel.Add("Group", group);
现在 XAML:
<TextBlock Text="{Binding Group.Title, Mode=TwoWay}"
Foreground="{StaticResource ListViewItemOverlayForegroundThemeBrush}"
Style="{StaticResource BaseTextBlockStyle}"
Height="60"
Margin="15,0,15,0"
FontWeight="SemiBold"/>
<TextBlock Text="{Binding Group.Subtitle}"
Foreground="{StaticResource ListViewItemOverlaySecondaryForegroundThemeBrush}"
Style="{StaticResource BaseTextBlockStyle}"
TextWrapping="NoWrap"
Margin="15,0,15,10"
FontSize="12"/>
这行得通。但是,如果我将数据源更改为 use MovieDataItem
,而不更改任何其他内容,则它不起作用;
我改变了电影的组。由于两者都有 Title 和 Subtitle 属性,我不必更改任何内容:
MovieDataItem movie = new MovieDataItem(Guid.NewGuid().ToString(), "My Movie", "Subtitle", String.Empty, "Description", String.Empty);
DefaultViewModel.Add("Group", movie);