在 tabitems 中加载列表框 - 使用哪个事件?

发布于 2024-08-22 21:47:42 字数 874 浏览 9 评论 0原文

假设我有一个包含一个窗口的应用程序。窗口内部是一个选项卡控件,带有三个选项卡项。每个 tabitem 内部都有一个用户控件。

在一个选项卡中我有“添加颜色”。在下一个选项卡中,我添加了水果。在第三个选项卡中,我有关系,用户可以在水果和颜色之间添加链接。这种关系显示在一个列表框中,如下所示:

Apple > Red
Pear  > Green

在同一选项卡的下面,我缺少水果列表框和缺少颜色列表框...即已添加但未在关系中链接的水果或颜色。我应该解释一下,这些数据全部存储在三个单独的文本文件中:fruits.txt、colors.txt 和relationships.txt。

我遇到的问题如下。目前,列表框等的填充是在 Usercontrol_loaded 事件上进行的。水果/颜色并不重要,因为单击添加按钮后,列表会重新加载。问题出在关系屏幕上。

假设用户运行该程序,然后单击关系选项卡以查看链接的内容。我们会说上面的例子已经在文本文件中。这样,这种关系就显现出来了——并且没有遗漏任何成果。然后,用户单击水果选项卡并添加水果,然后单击颜色选项卡并添加颜色。然后移至关系选项卡。 usercontrol_loaded 事件已经发生,因此这两个新添加的内容不会显示在列表框中。

如果我将代码移至 GotFocus 事件,用户将无法在任何列表框中进行选择,因为它会不断加载,因为单击会触发该事件。

除了提供刷新按钮之外,还有其他事件或方式可以在选项卡“切换到”时进行刷新吗?

感谢您的阅读。

...

编辑1:如果我将数据绑定到我在代码隐藏中构建的缺失水果列表,我仍然遇到同样的问题。每次他们跳出此选项卡并返回到它时,我都必须重新加载此列表(因为他们可能添加了水果或颜色,但现在丢失了)。

Lets say I have an application which comprises one window. Inside the window is a tabcontrol, with three tabitems. Inside each tabitem is a usercontrol.

In one tab I have Add color. In the next tab I have add Fruit. In the third tab I have relationships, where the user can add links between the fruit and the colors. This relationship is displayed in a listbox like:

Apple > Red
Pear  > Green

Below this in the same tab I have missing fruits listbox and a missing colors listbox... i.e. fruits or colors that have been added but not linked in the relationship. I should explain that this data is all stored in three seperate textfiles, fruits.txt, colors.txt and relationships.txt.

The problem I have is as follows. At the moment the populating of the listboxes etc is on Usercontrol_loaded event. It doesn't matter for fruit/colors, as after the add button is clicked, the list reloads. The problem is in the relationship screen.

Say the user runs the program, and clicks on the relationship tab to see what is linked. We'll say that the above example was already in the textfile. So that relationship shows up - and no missing fruits. The user then clicks the fruit tab and adds a fruit and then the color tab and adds a color. Then moves to the relationship tab. The usercontrol_loaded event has already occured, so these two new additions do not show in the listboxes.

If I move the code to GotFocus event, the user can't make selection in any listbox because it is constantly loading, as clicking fires the event.

Is there any other event or way I could have this refresh JUST when the tab has been "switched to", other than providing a refresh button?

Thanks for reading.

...

Edit 1: If I databind to a list of missing fruits which I build in the codebehind, I still have the same problem. I have to reload this list everytime they go jump off this tab and come back to it (because potentially they've added a fruit or a color, which is now missing).

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

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

发布评论

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

评论(3

您需要了解 MVVM 和更改通知的工作原理。如果您要跟踪绑定到 UI 的视图模型类中的可观察集合中的所有内容,则完全不需要使用事件或代码隐藏。

正如 wwosik 建议的那样,创建一个公开 ColorsFruitsRelationships 属性的类,这些属性都是可观察的集合。正如她/他没有建议但可能应该这样做一样,还公开了公共 MissingColorsMissingFruits 可观察集合。最后,公开公共 SelectedColorSelectedFruit 属性。

创建绑定控件:

<ListBox ItemsSource="{Binding Colors}" SelectedItem="{Binding SelectedColor}"/>
<ListBox ItemsSource="{Binding Fruits}" SelectedItem="{Binding SelectedFruit}"/>
<ListBox ItemsSource="{Binding Relationships}"/>
<ListBox ItemsSource="{Binding MissingColors}"/>
<ListBox ItemsSource="{Binding MissingFruits}"/>

实现一个 AddRelationship 方法,该方法添加由 SelectedColorSelectedFruit 组成的新关系。它还应该从相应的 MissingColorsMissingFruits 集合中删除颜色和水果。创建一个调用此方法的命令并将其绑定到 UI 中的某些内容。

就是这样。任何选项卡上的内容并不重要。用户查看事物的顺序并不重要。当用户添加关系、水果或颜色时,UI 将更新。

You need to understand how MVVM and change notification works. You don't need to use events or code-behind at all if you're tracking all of this stuff in observable collections in view model classes that are bound to the UI.

As wwosik suggests, create a class that exposes public Colors, Fruits, and Relationships properties that are all observable collections. As s/he didn't suggest but probably should have, also expose public MissingColors and MissingFruits observable collections. Finally, expose public SelectedColor and SelectedFruit properties.

Create bound controls:

<ListBox ItemsSource="{Binding Colors}" SelectedItem="{Binding SelectedColor}"/>
<ListBox ItemsSource="{Binding Fruits}" SelectedItem="{Binding SelectedFruit}"/>
<ListBox ItemsSource="{Binding Relationships}"/>
<ListBox ItemsSource="{Binding MissingColors}"/>
<ListBox ItemsSource="{Binding MissingFruits}"/>

Implement an AddRelationship method that adds a new relationship consisting of the SelectedColor and SelectedFruit. It should also remove the color and fruit from the respective MissingColors and MissingFruits collections. Create a command that calls this method and bind it to something in the UI.

That's it. It doesn't matter what tab anything is on. It doesn't matter what order the user views things in. When the user adds a relationship, or a fruit, or a color, the UI will get updated.

离鸿 2024-08-29 21:47:43

您需要将列表框绑定到 ViewModel 中的数据。这样,WPF 框架就可以取代对更新数据时刻的检测。

You need to bind your listboxes to the data from your ViewModel. This way the WPF framework overtakes the detection of the moment when to update the data.

离不开的别离 2024-08-29 21:47:43

WPF 不是 WinForm。您不需要自己填充列表框。

你有

class MyData{
   ObservableCollection<Color> Colors;
   ObservableCollection<Fruit> Fruits;
   ObservableCollection<Pairs> Pairs;

   public void MatchCurrentSelection(){
        var selectedColor = CollectionViewSource.GetDefaultView(Colors).CurrentItem;
        var selectedFruit = CollectionViewSource.GetDefaultView(Fruits).CurrentItem;
        if(selectedColor != null && selectedFruit != null){
             Colors.Remove(selectedColor);
             Fruits.Remove(selectedFruit);
             Pairs.Add(new Pair(selectedColor, selectedFruit));
        }
   }
} 

列表框

<ListBox ItemsSource="{Binding Colors}" IsSynchronizedWithCurrentItem="true"/>
<ListBox ItemsSource="{Binding Fruits}" IsSynchronizedWithCurrentItem="true"/>
<ListBox ItemsSource="{Binding Pairs}"/>

WPF is not WinForms. You don't populate ListBoxes by yourself.

You have

class MyData{
   ObservableCollection<Color> Colors;
   ObservableCollection<Fruit> Fruits;
   ObservableCollection<Pairs> Pairs;

   public void MatchCurrentSelection(){
        var selectedColor = CollectionViewSource.GetDefaultView(Colors).CurrentItem;
        var selectedFruit = CollectionViewSource.GetDefaultView(Fruits).CurrentItem;
        if(selectedColor != null && selectedFruit != null){
             Colors.Remove(selectedColor);
             Fruits.Remove(selectedFruit);
             Pairs.Add(new Pair(selectedColor, selectedFruit));
        }
   }
} 

ListBoxes

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