gpt4 book ai didi

c# - 自定义 CompositeCollection 不工作

转载 作者:太空宇宙 更新时间:2023-11-03 13:25:05 25 4
gpt4 key购买 nike

我试过编写自定义 CompositeCollectionCollectionContainer几次,我正要放弃。这就是我所拥有的。看起来很简单。

主页.xaml

<phone:PhoneApplicationPage.Resources>
<vm:MainViewModel x:Key="ViewModel"/>
</phone:PhoneApplicationPage.Resources>

<phone:Panorama DataContext="{StaticResource ViewModel}">
<phone:Panorama.ItemsSource>
<app:CompositeCollection>
<app:CompositeContainer Collection="{Binding People}"/>
<models:PersonModel FirstName="John" LastName="Doe"/>
</app:CompositeCollection>
</phone:Panorama.ItemsSource>

<phone:Panorama.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding FirstName}"/>
<TextBlock Text="{Binding LastName}"/>
</StackPanel>
</DataTemplate>
</phone:Panorama.ItemTemplate>
</phone:Panorama>

复合集合.cs

namespace PanoramaApp1
{
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;

public class CompositeCollection : ObservableCollection<object>
{
Collection<IEnumerable> _collections;

public CompositeCollection()
: base()
{
_collections = new Collection<IEnumerable>();
}

public CompositeCollection(IEnumerable<object> collection)
: this()
{
if (null == collection)
{
throw new ArgumentNullException("collection");
}
foreach (object obj in collection)
{
base.Add(obj);
}
}

public CompositeCollection(List<object> list)
: this()
{
if (null == list)
{
throw new ArgumentNullException("list");
}
foreach (object obj in list)
{
base.Add(obj);
}
}

protected override void ClearItems()
{
base.Clear();
_collections.Clear();
}

protected override void InsertItem(int index, object item)
{
CompositeContainer container = item as CompositeContainer;
if (null != container && null != container.Collection)
{
InsertContainer(index, container);
}
else
{
base.InsertItem(index, item);
}
}

private void InsertContainer(int index, CompositeContainer container)
{
IEnumerable collection = _collections[index] = container.Collection;
foreach (object obj in collection)
{
base.InsertItem(index++, obj);
}
}

protected override void RemoveItem(int index)
{
IEnumerable collection = _collections[index];
if (null != collection)
{
RemoveContainer(index, collection);
}
else
{
base.RemoveItem(index);
}
}

private void RemoveContainer(int index, IEnumerable collection)
{
foreach (object obj in collection)
{
base.RemoveItem(index++);
}
_collections.RemoveAt(index);
}

protected override void SetItem(int index, object item)
{
RemoveItem(index);
InsertItem(index, item);
}
}
}

复合容器.cs

namespace PanoramaApp1
{
using System.Collections;
using System.Windows;

public class CompositeContainer : DependencyObject
{
public IEnumerable Collection
{
get { return (IEnumerable)GetValue(CollectionProperty); }
set { SetValue(CollectionProperty, value); }
}

public static readonly DependencyProperty CollectionProperty =
DependencyProperty.Register(
"Collection",
typeof(IEnumerable),
typeof(CompositeContainer),
new PropertyMetadata(null));
}
}

MainViewModel.cs

using Models;
using System.Collections.ObjectModel;

namespace ViewModels
{
public class MainViewModel
{
public MainViewModel()
{
this.People = new ObservableCollection<object>();
People.Add(new PersonModel("Jane", "Doe"));
People.Add(new PersonModel("Joe", "Doe"));
People.Add(new PersonModel("James", "Doe"));
}

public ObservableCollection<object> People { get; private set; }
}
}

PersonModel.cs

using System.ComponentModel;

namespace Models
{
public class PersonModel : INotifyPropertyChanging, INotifyPropertyChanged
{
public event PropertyChangingEventHandler PropertyChanging;

public event PropertyChangedEventHandler PropertyChanged;

private string _firstName;

private string _lastName;

public PersonModel(string firstName)
{
this.FirstName = firstName;
}

public PersonModel(string firstName, string lastName)
: this(firstName)
{
this.LastName = lastName;
}

public string FirstName
{
get { return _firstName; }
set
{
RaisePropertyChanging("FirstName");
_firstName = value;
RaisePropertyChanged("FirstName");
}
}

public string LastName
{
get { return _lastName; }
set
{
RaisePropertyChanging("LastName");
_lastName = value;
RaisePropertyChanged("LastName");
}
}

private void RaisePropertyChanging(string propertyName)
{
if (null != PropertyChanging)
{
PropertyChanging(this, new PropertyChangingEventArgs(propertyName));
}
}

private void RaisePropertyChanged(string propertyName)
{
if (null != PropertyChanged)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}

如果我在 xaml 中注释掉 PersonModel 对象,应用程序将启动,但不会填充全景图。如果我不加注释,我会得到一个非常无用的异常,说 PersonModel 对象“无法实例化”。ItemsSource ItemsControl 的属性类型为 IEnumerable看来我正在正确枚举容器。帮助?请?哈哈


编辑:谢谢,无参数构造函数解决了第一个问题。第二个问题仍然存在:它现在确实用 PersonModel 对象填充了第二个 panoramaitem,但第一个 panoramaitem 仍然是空的。似乎它将整个第一个 panoramaitem 绑定(bind)到 IEnumerable 而不是插入单个元素。

设计师展示了这个:i.imgur.com/4fAPe0N.jpg模拟器显示:i.imgur.com/UzdyMqk.png i.imgur.com/SWJZ28H.png

最佳答案

您在 XAML 中初始化一个 PersonModel,它将调用您的代码中不存在的默认构造函数 => 只需将其添加到 PersonModel.cs 即可解决该部分:

public PersonModel() {}

xaml 中的参数不会用作构造函数参数,但它们会在创建对象后使用属性 setter 设置值,就像

new PersonModel() { FirstName="John", LastName="Doe" };

关于c# - 自定义 CompositeCollection 不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22681836/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com