我的应用程序中有ListView
,目前填充了2个项目。
<ListView Name="lstViewFolderSettings" Grid.Column="0" Grid.ColumnSpan="3" Grid.Row="0" SelectionMode="Single" SelectionChanged="lstViewFolderSettings_SelectionChanged">
<ListView.View>
<GridView>
<GridViewColumn Width="100" Header="Type" DisplayMemberBinding="{Binding Name}" />
<GridViewColumn Width="250" Header="Folder" DisplayMemberBinding="{Binding FolderPath}" />
<GridViewColumn Width="350" Header="XPath" DisplayMemberBinding="{Binding XPath}" />
</GridView>
</ListView.View>
</ListView>
然后我将ItemsSource
设置为以下
lstViewFolderSettings.ItemsSource = fileSeperationSettings.FileSettings;
在SelectionChanged
事件中,我获得了填充某些控件的所选项目。然后我点击保存我然后更新我的收藏并再次重置ItemsSource
lstViewFolderSettings.ItemsSource = null;
lstViewFolderSettings.ItemsSource = fileSeperationSettings.FileSettings;
我必须先设置为null,否则ListView
不会在视图中更新
这一切似乎都能正常工作,直到我在同一项目上更改我的选择两次。
即。
选择项目1 - &gt;改变 - &gt;更新
选择项目2
选择项目1
选择项目2 - &gt; BANG!
ArgumentException未处理
已添加具有相同密钥的项目。
堆栈跟踪:
at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
at System.Collections.Generic.Dictionary`2..ctor(IDictionary`2 dictionary, IEqualityComparer`1 comparer)
at System.Windows.Controls.Primitives.Selector.InternalSelectedItemsStorage..ctor(InternalSelectedItemsStorage collection, IEqualityComparer`1 equalityComparer)
at System.Windows.Controls.Primitives.Selector.SelectionChanger.ApplyCanSelectMultiple()
at System.Windows.Controls.Primitives.Selector.SelectionChanger.End()
at System.Windows.Controls.Primitives.Selector.SetSelectedHelper(Object item, FrameworkElement UI, Boolean selected)
at System.Windows.Controls.Primitives.Selector.NotifyIsSelectedChanged(FrameworkElement container, Boolean selected, RoutedEventArgs e)
at System.Windows.Controls.Primitives.Selector.OnSelected(Object sender, RoutedEventArgs e)
at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
at System.Windows.UIElement.RaiseEvent(RoutedEventArgs e)
at System.Windows.Controls.ListBoxItem.OnSelected(RoutedEventArgs e)
---更新--- SelectionChanged事件处理程序代码。
private void lstViewFolderSettings_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
m_SelectedSetting = lstViewFolderSettings.SelectedItem as FileSetting;
txtFolder.Text = m_SelectedSetting.FolderPath;
txtType.Text = m_SelectedSetting.Name;
txtXPath.Text = m_SelectedSetting.XPath;
e.Handled = true;
}
- 更新----
所以我现在有了这个
ObservableCollection<FileSetting> _fileSettings;
public ObservableCollection<FileSetting> FileSettings
{
get
{
if (_fileSettings == null)
{
FileSeperationSettings fileSeperationSettings = m_config.GetSection("fileSeperationSettings") as FileSeperationSettings;
_fileSettings = new ObservableCollection<FileSetting>(fileSeperationSettings.FileSettings.Cast<FileSetting>());
}
return _fileSettings;
}
}
我在此系列中添加和删除
FileSettings.Add(fsSetting);
FileSettings.Remove(fsSetting);
我得到了所选项目
m_SelectedSetting = lstViewFolderSettings.SelectedItem as FileSetting;
txtFolder.Text = m_SelectedSetting.FolderPath;
txtType.Text = m_SelectedSetting.Name;
txtXPath.Text = m_SelectedSetting.XPath;
我更新了项目
FileSetting fs = FileSettings.First(x => x.Name == m_SelectedSetting.Name);
fs.Name = txtType.Text;
fs.FolderPath = txtFolder.Text;
fs.XPath = txtXPath.Text;
我做更新后再发生错误,然后第二次更改所选项目......
答案 0 :(得分:1)
我通过阅读以下can't clear WPF ListBox.SelectedItems collection解决了这个问题。我意识到它不会删除我的selectedItem的原因是因为它在集合中不存在(HashCode已经改变),或者像那样疯狂的东西......
所以我将selectionChanged事件更改为以下
FileSetting selectedItem;
private void lstViewFolderSettings_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
selectedItem = lstViewFolderSettings.SelectedItem as FileSetting;
txtFolder.Text = selectedItem.FolderPath;
txtType.Text = selectedItem.Name;
txtXPath.Text = selectedItem.XPath;
lstViewFolderSettings.UnselectAll();
}
所以我现在自己跟踪所选项目。这意味着我可以随意设置和重新设置ItemsSource。
答案 1 :(得分:0)
我将远离代码隐藏,并更多地使用数据绑定。
您的收藏集应该是用户界面DataContext
:
public class MyViewModelOrCodeBehindClass
{
public FileSetting SelectedItem { get; set; }
public ObservableCollection<FileSetting> FileSettings
{
get;
private set;
}
public MyViewModel()
{
FileSettings = new ObservableCollection<FileSetting>();
// If you're using codebehind rather than having something
// else set this class as the datacontext:
DataContext = this;
}
}
在您看来:
<ListView ItemsSource="{Binding FileSettings}" SelectedItem="{Binding SelectedItem}" />
<TextBlock Text="{Binding SelectedItem.Folder}" />
<TextBlock Text="{Binding SelectedItem.Name}" />
<TextBlock Text="{Binding SelectedItem.XPath}" />
在您的代码隐藏/视图模型中,您可以只添加/删除项目,数据绑定将完成剩下的工作。更好的是,如果列表中的每个项目都实现INotifyPropertyChanged
,那么对这些项目的编辑也将在UI中自动更新。你根本不需要真正处理SelectionChanged
。