WPF:ListView和编辑ListViewItem
我希望能够选择一个项目,然后编辑其标签:
- 选择一个项目
- 项目突出显示
- 点击它的标签
- Label的TextBlock替换为TextBox
- 修改标签
- 一次只能编辑一个项目
结束编辑:
- 点击项目的图标:
- TextBox将替换为TextBlock
- 项目仍然突出显示
- 点击另一个项目:
- TextBox将替换为TextBlock
- 已编辑的项目未被选中
- 选中并突出显示单击的项目
- 单击窗口的任何其他区域:
- TextBox将替换为TextBlock
- 编辑的项目仍然突出显示
该行为应该与Windows资源管理器中的行为非常相似。
我设法完成了大部分要求。 我仍然得到随机结果。 例如,在第一次启动时,我可以直接点击标签进行编辑。 项目本身仍未突出显示。 这仅在开始时发生。
使用滚动条也不会将焦点从列表项中移除。 这允许同时编辑多个项目。
XAML
码
public partial class DailyImages { public DailyImages() { InitializeComponent(); ViewModel.DailyImages dailyImages = new ViewModel.DailyImages(); _mediaItemList.DataContext = dailyImages; } private void OnClickLabelBlock(object sender, MouseButtonEventArgs e) { TextBlock notes = sender as TextBlock; if (notes == null) return; MediaItem selectedMedia = notes.DataContext as MediaItem; if (selectedMedia == null) return; // Multiple items might be selected // Clear all selected items _mediaItemList.SelectedItems.Clear(); // Reselect selectedMedia.IsSelected = true; selectedMedia.IsEditing = true; Mouse.Capture(this, CaptureMode.SubTree); } private void OnTextLostFocus(object sender, RoutedEventArgs e) { TextBox textBox = sender as TextBox; if (textBox == null) return; MediaItem mediaItem = textBox.DataContext as MediaItem; if (mediaItem == null) return; // End the label editing mediaItem.IsEditing = false; ReleaseMouseCapture(); } private void OnClickMediaList(object sender, MouseButtonEventArgs e) { // End the label editing foreach (MediaItem mediaItem in _mediaItemList.Items) mediaItem.IsEditing = false; ReleaseMouseCapture(); } }
MediaItem.cs
public class MediaItem : INotifyPropertyChanged { private bool _isEditing; private bool _isSelected; private string _label; public MediaItem() { IsEditing = false; _isSelected = false; } public bool IsEditing { get { return _isEditing; } set { if (_isEditing == value) return; _isEditing = value; OnPropertyChanged("IsEditing"); } } public string Label { get { return _label; } set { _label = value; OnPropertyChanged("Label"); } } public DateTime Date { get; set; } public string IconPath { get; set; } public bool IsSelected { get { return _isSelected; } set { _isSelected = value; OnPropertyChanged("IsSelected"); } } public event PropertyChangedEventHandler PropertyChanged; [NotifyPropertyChangedInvocator] protected virtual void OnPropertyChanged(string propertyName) { PropertyChangedEventHandler handler = PropertyChanged; if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); } }
DailyImages.cs
public class DailyImages { private ObservableCollection _mediaItems; public DailyImages() { _mediaItems = new ObservableCollection(); _mediaItems.Add(new MediaItem {Label = "Image 1", IconPath = "Resources/Icon1.png"}); _mediaItems.Add(new MediaItem {Label = "Image 2", IconPath = "Resources/Icon2.png"}); _mediaItems.Add(new MediaItem {Label = "Image 3", IconPath = "Resources/Icon3.png"}); _mediaItems.Add(new MediaItem {Label = "Image 4", IconPath = "Resources/Icon4.png"}); _mediaItems.Add(new MediaItem {Label = "Image 5", IconPath = "Resources/Icon5.jpg"}); _mediaItems.Add(new MediaItem {Label = "Image 6", IconPath = "Resources/Icon6.png"}); _mediaItems.Add(new MediaItem {Label = "Image 7", IconPath = "Resources/Icon7.png"}); _mediaItems.Add(new MediaItem {Label = "Image 8", IconPath = "Resources/Icon8.png"}); _mediaItems.Add(new MediaItem {Label = "Image 9", IconPath = "Resources/Icon9.png"}); } public ObservableCollection MediaItems { get { return _mediaItems; } set { _mediaItems = value; } } }
感谢阅读长篇文章。
我在StackOverflow中搜索并阅读了很多答案,但这些答案对我来说都不是很好。
例如:
- 控件如何在该控件外部处理鼠标单击?
- 单击空白区域时如何处理事件?
- 如何捕获鼠标单击WPF中ListBox中的项目?
您可能希望捕获listview上的scrollevent并显式删除对元素的焦点。
ScrollViewer scrollViewer = GetVisualChild(mTreeView); scrollViewer.ScrollChanged += new ScrollChangedEventHandler(scrollViewer.....
并在处理程序内删除焦点。
查看此stackoverflow页面,以便将焦点从元素WPF移开:如何以编程方式从TextBox中删除焦点
也许最好将IsReadonly属性切换到不同的状态? 然后,您将不再需要切换可见性。 此外,在这种情况下更换模板更好。