如何在 WPF 列表框中反映顺序更改

发布于 2024-11-25 09:49:47 字数 1965 浏览 2 评论 0原文

我有(我感觉的)一个非常简单的场景,我似乎无法弄清楚。我在这里(即 StackOverflow.com)寻找解决方案,但似乎找不到任何人遇到我的确切问题。我没有按照标准对列表框进行排序;我只是希望我的列表框能够反映我的集合中项目的顺序。

我正在使用 Caliburn.Micro 将底层集合绑定到 WPF ListBox。我只是希望能够允许用户使用我提供的按钮在列表中上下移动项目。功能很好用!但是,ListBox 将不会反映新集合的顺序。

这是一个简单的 ViewModel:

public class MyViewModel : PropertyChangedBase
{
  private readonly IObservableCollection<SimpleItem> _items;
  private SimpleItem _selectedItem;

  public MyViewModel()
  {
    _items = new BindableCollection<SimpleItems>();
    _items.Add(new SimpleItem("Item 1"));
    _items.Add(new SimpleItem("Item 2"));
    _items.Add(new SimpleItem("Item 3"));
  }
  public IObservableCollection<SimpleItem> Items
  {
    get { return _items; }
  }

  public SimpleItem SelectedItem
  {
    get { return _selectedItem; }
    set
    {
      _selectedItem = value;
      NotifyOfPropertyChanged(() => SelectedItem);
    }
  }
}

这是绑定到我的 ViewModel 的 Xaml(再次使用 Caliburn.Micro):

<ListBox x:Name="Items">
  <ListBox.ItemTemplate>
    <DataTemplate>
      <TextBlock Text="{Binding Caption}"/>
    </DataTemplate>
  </ListBox.ItemTemplate>
</ListBox>

结果完美地显示了我的 ListBox 中的项目:

Item 1
Item 2
Item 3

现在,假设用户想要移动 Item 2 位于第 1 项之上。他们选择 Item 2,然后单击名为 MoveUp 的按钮。我的 ViewModel 中有一个名为 MoveUp() 的方法,它执行以下逻辑(为简洁起见,进行了简化):

public void MoveUp()
{
  var item = SelectedItem;
  var index = Items.IndexOf(item);

  Items.Remove(item);
  Items.Insert(index - 1, item);

  SelectedItem = item;
}

不幸的是,ListBox 没有反映新的顺序...告诉视图列表框刷新列表框的最佳方法是什么?显示而不诉诸代码隐藏?

更新:2011年7月20日

我发现了这个问题。问题是我的 SimpleItems 集合实际上是父“SimpleItem”的子集。因此,当用户单击“MoveUp”时,我会查找父 SimpleItem 并直接引用它的子项。问题是子级没有绑定到 IObservableCollection 实例。我必须改变我的逻辑来找到可观察的集合,它现在可以工作了!感谢@devdigital 的帮助!

-=吕克

I have (what I feel to be) a very simple scenario that I can't seem to figure out. I've looked around here (ie. StackOverflow.com) for a solution, but can't seem to find anybody with my exact problem. I'm not sorting my listbox on a criteria; I simply want my listbox to reflect the order of the items in my collection.

I'm using Caliburn.Micro to bind an underlying collection to a WPF ListBox. I simply want to be able to allow the user to move items up and down the list using buttons that I've provided. The functionality works great! However, the ListBox will not reflect the new collection's order.

Here is a simple ViewModel:

public class MyViewModel : PropertyChangedBase
{
  private readonly IObservableCollection<SimpleItem> _items;
  private SimpleItem _selectedItem;

  public MyViewModel()
  {
    _items = new BindableCollection<SimpleItems>();
    _items.Add(new SimpleItem("Item 1"));
    _items.Add(new SimpleItem("Item 2"));
    _items.Add(new SimpleItem("Item 3"));
  }
  public IObservableCollection<SimpleItem> Items
  {
    get { return _items; }
  }

  public SimpleItem SelectedItem
  {
    get { return _selectedItem; }
    set
    {
      _selectedItem = value;
      NotifyOfPropertyChanged(() => SelectedItem);
    }
  }
}

Here is the Xaml that binds to my ViewModel (again, using Caliburn.Micro):

<ListBox x:Name="Items">
  <ListBox.ItemTemplate>
    <DataTemplate>
      <TextBlock Text="{Binding Caption}"/>
    </DataTemplate>
  </ListBox.ItemTemplate>
</ListBox>

The results display the items in my ListBox perfectly:

Item 1
Item 2
Item 3

Now, assume the user wants to move Item 2 above Item 1. They select Item 2, and then click a button named MoveUp. I have a method in my ViewModel called MoveUp() that does the following logic (simplified for brevity):

public void MoveUp()
{
  var item = SelectedItem;
  var index = Items.IndexOf(item);

  Items.Remove(item);
  Items.Insert(index - 1, item);

  SelectedItem = item;
}

Unfortunately, the ListBox does not reflect the new order... What is the best way to tell the view that the listbox to refresh the display without resorting to the code-behind?

UPDATE: July 20, 2011

I found the problem. The problem was that my collection of SimpleItems was actually a subset of a parent 'SimpleItem'. Therefore, when the user clicked on 'MoveUp', I would do a lookup on the parent SimpleItem and reference it's children directly. The problem was that the children were not bound to the IObservableCollection instance. I had to change my logic to find the observable collection instead and it works now! Thank you @devdigital for your help!

-= Luc

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

相思故 2024-12-02 09:49:47

如果在集合中添加和删除项目,并且绑定设置正确,则视图中的更新应该是自动的。

您是否在 MoveUp 方法中设置了断点以确保那里确实发生了任何事情?我将确保 SelectedItem 正确绑定(您不会在代码中显示此绑定)并且在访问它时不为空。我还会注释掉执行插入的行,并确保删除调用实际上会导致您的视图正确更新。

If items are getting added and removed from your collection, and your binding is set up correctly, the updates in the view should be automatic.

Have you set breakpoints in the MoveUp method to ensure that anything is actually happening there? I would make sure SelectedItem is bound properly (you don't show this binding in your code) and is not null when it is accessed. I would also comment out the line that does the Insert and ensure that the Remove call actually causes your view to update properly.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文