更新列表框而不丢失所选项目,WPF
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12808479/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Updating listbox without losing selected item, WPF
提问by Dmitry Dyachkov
Listbox is updated every sec and during work I need to select some of it's items and execute a command, which is impossible, because listbox is updated and loses it's selected item.
列表框每秒钟更新一次,在工作期间我需要选择其中的一些项目并执行命令,这是不可能的,因为列表框已更新并丢失了所选项目。
ObservableCollection is the ViewModel of my list.
ObservableCollection 是我列表的 ViewModel。
I have some options in mind and perhaps there are better solutions:
我有一些选择,也许有更好的解决方案:
Detect new items in the list to be propagated and add new items to ObservableCollection without reinitializing ObservableCollection
Detect changes in the old items and updated their fields if necessary.
检测列表中要传播的新项目并将新项目添加到 ObservableCollection 而不重新初始化 ObservableCollection
检测旧项目的变化并在必要时更新它们的字段。
This is somewhat cumbersome, though not difficult, but are there any other options?
这有点麻烦,虽然不难,但还有其他选择吗?
Update, solution that I have
更新,我有的解决方案
I've chosen the 3-d part: before an update has started, I save selected index of sorted collection and load a new collection and compare vs. old collection. I Know, this is not efficient, but for the current application this fits quite well: collections will never be more than some hundreds, ordinarily, no more 100. Each element of collection supports eager and lazy loading. And if there are changed items, they load their content from server, while other remain intact. And then I update observable collection, update changed items from server and set selected index in the viewmodel. Selecting an item manually solves the problem of losing focus after update.
我选择了 3-d 部分:在更新开始之前,我保存排序集合的选定索引并加载一个新集合并比较与旧集合。我知道,这并不高效,但对于当前的应用程序来说,这非常适合:集合永远不会超过数百个,通常不会超过 100 个。集合的每个元素都支持预先加载和延迟加载。如果有更改的项目,它们会从服务器加载它们的内容,而其他保持不变。然后我更新可观察集合,从服务器更新更改的项目并在视图模型中设置选定的索引。手动选择项目,解决更新后失去焦点的问题。
采纳答案by Tony Hopkinson
Save the selected item's key before the list is updated. Find it in the new version of the list, and re-select it. Don't rely on the original reference, and allow for some other fellow removing it from the new list to select from.
在更新列表之前保存所选项目的密钥。在列表的新版本中找到它,然后重新选择它。不要依赖原始参考,并允许其他人将其从新列表中删除以供选择。
回答by Michael L Perry
This sometimes happens if you change the order of the items in the list box's ItemsSource. When you remove the item temporarily to insert it somewhere else, WPF will prematurely set the SelectedItem to null. Then when you add it back in, it won't be selected.
如果您更改列表框的 ItemsSource 中项目的顺序,有时会发生这种情况。当您临时删除项目以将其插入其他位置时,WPF 会过早地将 SelectedItem 设置为 null。然后当你重新添加它时,它不会被选中。
Here's a workaround in the form of a behavior that you can attach to your list box.
这是您可以附加到列表框的行为形式的解决方法。
http://www.codeproject.com/Tips/802806/Preserve-the-Selected-Item-of-a-WPF-List-Box
http://www.codeproject.com/Tips/802806/Preserve-the-Selected-Item-of-a-WPF-List-Box
回答by sayed saad
I'm thinking of changing your binding collection to a new instance of the current collection. Once you start selecting items. once you finish set the binding back to the original collection
我正在考虑将您的绑定集合更改为当前集合的新实例。一旦你开始选择项目。完成后将绑定设置回原始集合
回答by nywooz
What if you
如果你
add a class to your select:
<select title="" id="" class="initMySelect"> </select>target the class to repopulate the select
添加一个类到您的选择:
<select title="" id="" class="initMySelect"> </select>目标类以重新填充选择
Example from an object:
来自对象的示例:
var object={
"6db01de6-a1e8-4ea6-bf01-4562b56468b9": {
"UID": "6db01de6-a1e8-4ea6-bf01-4562b56468b9",
"name": "aa",
"description": "aa"
},
"284c3172-268a-4342-d3f0-d00fafd3d482": {
"UID": "284c3172-268a-4342-d3f0-d00fafd3d482",
"name": "bb",
"description": "bb"
},
"b124f4df-6caa-43e8-eb97-536076b4832b": {
"UID": "b124f4df-6caa-43e8-eb97-536076b4832b",
"name": "cc",
"description": "cc"
},
"c934634a-0775-41bd-d72a-d8900ebcbdd1": {
"UID": "c934634a-0775-41bd-d72a-d8900ebcbdd1",
"name": "dd",
"description": "dd"
},
"fb5b8dcb-b9fb-405d-9fcf-3f551727459a": {
"UID": "fb5b8dcb-b9fb-405d-9fcf-3f551727459a",
"name": "ee",
"description": "ee"
},
"a98f3449-bb55-46e3-b9ce-f9e2dd6d74a9": {
"UID": "a98f3449-bb55-46e3-b9ce-f9e2dd6d74a9",
"name": "ff",
"description": "ff"
}
}
function initMySelect(value) {
var options = "";
var selected = "";
$.each(object, function(k, v) {
if (value === v.UID) {
selected = 'selected = "selected"';
} else {
selected = "";
}
options += '<option ' + selected + ' value=' + v.UID + '>' + v.name + '</option>';
});
$('.initMySelect').html(options);
}
- Whatever CRUD you making, will reinitialise the class, meaning the class will hold all the Up-to-date changes. so after any add, update, delete, exe your function
- 无论您制作什么 CRUD,都会重新初始化该类,这意味着该类将保留所有最新的更改。所以在添加、更新、删除、执行你的函数之后
initMySelect();
when viewing your select the selected index will still be there as selected and the extra Crud changes u made will appear in your select. 4. Function to add event listener on button which send the selected value to initMySelect
查看您的选择时,所选索引仍将保留为已选择,您所做的额外 Crud 更改将出现在您的选择中。4. 在按钮上添加事件监听器的功能,将选择的值发送到 initMySelect
var el = document.getElementById("repopulateSelect");
el.addEventListener("click", function() {
initMySelect(document.getElementById("selectTest").value);
}, false);

