gpt4 book ai didi

wpf - 可观察链表

转载 作者:行者123 更新时间:2023-12-05 00:03:23 26 4
gpt4 key购买 nike

在我的 WPF 应用程序中,我有一个 ItemsControl,其项目值取决于前一项 显示 .

ViewModel 是一个分割成可变长度部分的音频文件,我需要以这种方式显示它,右侧显示一个 DateTime,这就是我需要计算的(我只知道每个部分的长度,我需要计算它开始和结束的实际时间,以及 ItemsControl 上的位置)。

--
----
------------
--
--------------------

我的第一种方法是使用 ObservableCollection<MyviewModel>但很快就发生了一些恐怖事件:

5 路多重绑定(bind),其中 IMultiValueConverter我会计算要返回的值并将 DataContext 的属性设置为该值,因为我只知道运行时的前一个元素。

前一个元素是使用 Relativesource.PreviousData 上的绑定(bind)发送的.

现在我的问题是,在从 Converter 设置一个值(这显然是一件坏事)并实际让它工作之后,常规 Collection 在其元素中没有顺序的概念,所以当更进一步时我想在其余部分中间添加一个音频部分,显示困惑。

此外,当我要实现更多业务逻辑时,我可能需要访问在此转换器中计算的音频部分的开始和结束,如果它还没有显示怎么办......?

所以这种方法在几个层面上都是错误的。

那是我开始谷歌搜索并发现 LinkedList的地方.现在我正在尝试创建一个基本上是 Observable LinkedList 的类(我不需要它是通用的):
public class ObservableSegmentLinkedList : LinkedList<MyViewModel>, INotifyCollectionChanged
{
//Overrides ???

#region INotifyCollectionChanged Members

public event NotifyCollectionChangedEventHandler CollectionChanged;
public void OnNotifyCollectionChanged(NotifyCollectionChangedEventArgs e)
{
if (CollectionChanged != null)
{
CollectionChanged(this, e);
}
}

#endregion
}

问题的核心是我无法覆盖修改集合的方法(Addfirst、AddLast 等),所以我无法正确调用 OnNotifyCollectionChanged ......

所以我想我可以为这些方法中的每一种方法进行重载,但这听起来很讨厌......

简而言之:我需要某种集合,其中每个项目都知道前一个项目的详细信息,以便计算它自己的一个属性。

有什么线索吗?这甚至是一个好的解决方案吗?

谢谢!

附录,ViewModel 看起来像:
public class MyViewModel : INotifyPropertyChanged
{
private DateTime m_SegmentLength;
public DateTime SegmentLength
{
get { return m_SegmentLength; }
set
{
m_SegmentLength = value;
NotifyPropertyChanged("SegmentLength");
}
}

private DateTime m_SegmentAdvert;
public DateTime SegmentAdvert
{
get { return m_SegmentAdvert; }
set
{
m_SegmentAdvert = value;
NotifyPropertyChanged("SegmentAdvert");
}
}

#region INotifyPropertyChanged Members

public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String prop)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(prop));
}

#endregion
}

编辑:我想我会尝试结合 Thomas 和 Will 的答案:我将使用组合(即我在我的自定义对象中保留一个 LinkedList 的实例而不是从它继承)并重新定义要使用的方法(AddAfter、AddFirst等),我将在调用实际的 LinkedList 方法后调用 OnNotifyPropertychanged。这有点工作,但我想我的问题不会有任何优雅的解决方案......

最佳答案

好的,我制作了一个支持 IEnumerable 的自定义泛型类并且被用作 LinkedList<T> ,唯一的区别是 WPF 会收到更改通知。

请注意,此解决方案仅适用于相当小的集合,我最多只需要管理大约 30 个元素,所以对我来说没问题,但每次修改此集合时,它都会被视为“重置”。

解决方案如下:

    /// <summary>
/// This class is a LinkedList that can be used in a WPF MVVM scenario. Composition was used instead of inheritance,
/// because inheriting from LinkedList does not allow overriding its methods.
/// </summary>
/// <typeparam name="T"></typeparam>
public class ObservableLinkedList<T> : INotifyCollectionChanged, IEnumerable
{
private LinkedList<T> m_UnderLyingLinkedList;

#region Variables accessors
public int Count
{
get { return m_UnderLyingLinkedList.Count; }
}

public LinkedListNode<T> First
{
get { return m_UnderLyingLinkedList.First; }
}

public LinkedListNode<T> Last
{
get { return m_UnderLyingLinkedList.Last; }
}
#endregion

#region Constructors
public ObservableLinkedList()
{
m_UnderLyingLinkedList = new LinkedList<T>();
}

public ObservableLinkedList(IEnumerable<T> collection)
{
m_UnderLyingLinkedList = new LinkedList<T>(collection);
}
#endregion

#region LinkedList<T> Composition
public LinkedListNode<T> AddAfter(LinkedListNode<T> prevNode, T value)
{
LinkedListNode<T> ret = m_UnderLyingLinkedList.AddAfter(prevNode, value);
OnNotifyCollectionChanged();
return ret;
}

public void AddAfter(LinkedListNode<T> node, LinkedListNode<T> newNode)
{
m_UnderLyingLinkedList.AddAfter(node, newNode);
OnNotifyCollectionChanged();
}

public LinkedListNode<T> AddBefore(LinkedListNode<T> node, T value)
{
LinkedListNode<T> ret = m_UnderLyingLinkedList.AddBefore(node, value);
OnNotifyCollectionChanged();
return ret;
}

public void AddBefore(LinkedListNode<T> node, LinkedListNode<T> newNode)
{
m_UnderLyingLinkedList.AddBefore(node, newNode);
OnNotifyCollectionChanged();
}

public LinkedListNode<T> AddFirst(T value)
{
LinkedListNode<T> ret = m_UnderLyingLinkedList.AddFirst(value);
OnNotifyCollectionChanged();
return ret;
}

public void AddFirst(LinkedListNode<T> node)
{
m_UnderLyingLinkedList.AddFirst(node);
OnNotifyCollectionChanged();
}

public LinkedListNode<T> AddLast(T value)
{
LinkedListNode<T> ret = m_UnderLyingLinkedList.AddLast(value);
OnNotifyCollectionChanged();
return ret;
}

public void AddLast(LinkedListNode<T> node)
{
m_UnderLyingLinkedList.AddLast(node);
OnNotifyCollectionChanged();
}

public void Clear()
{
m_UnderLyingLinkedList.Clear();
OnNotifyCollectionChanged();
}

public bool Contains(T value)
{
return m_UnderLyingLinkedList.Contains(value);
}

public void CopyTo(T[] array, int index)
{
m_UnderLyingLinkedList.CopyTo(array, index);
}

public bool LinkedListEquals(object obj)
{
return m_UnderLyingLinkedList.Equals(obj);
}

public LinkedListNode<T> Find(T value)
{
return m_UnderLyingLinkedList.Find(value);
}

public LinkedListNode<T> FindLast(T value)
{
return m_UnderLyingLinkedList.FindLast(value);
}

public Type GetLinkedListType()
{
return m_UnderLyingLinkedList.GetType();
}

public bool Remove(T value)
{
bool ret = m_UnderLyingLinkedList.Remove(value);
OnNotifyCollectionChanged();
return ret;
}

public void Remove(LinkedListNode<T> node)
{
m_UnderLyingLinkedList.Remove(node);
OnNotifyCollectionChanged();
}

public void RemoveFirst()
{
m_UnderLyingLinkedList.RemoveFirst();
OnNotifyCollectionChanged();
}

public void RemoveLast()
{
m_UnderLyingLinkedList.RemoveLast();
OnNotifyCollectionChanged();
}
#endregion

#region INotifyCollectionChanged Members

public event NotifyCollectionChangedEventHandler CollectionChanged;
public void OnNotifyCollectionChanged()
{
if (CollectionChanged != null)
{
CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
}

#endregion

#region IEnumerable Members

IEnumerator IEnumerable.GetEnumerator()
{
return (m_UnderLyingLinkedList as IEnumerable).GetEnumerator();
}

#endregion
}

正如@AndrewS 在评论中提到的那样,应该将 LinkedListNode 替换为从其 List 属性返回 ObservableLinkedList 的自定义类。

关于wpf - 可观察链表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6996425/

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