gpt4 book ai didi

wpf - 我如何(完全)在 ListBox 中实现就地编辑?

转载 作者:行者123 更新时间:2023-12-01 14:31:14 25 4
gpt4 key购买 nike

我正在构建一个应用程序,其中 ListBox 显示其项目的 Description 属性。我想实现与您在 Windows 资源管理器中编辑文件名时发现的相同类型的就地编辑功能,我发现它需要大量工作。

到目前为止,我所拥有的是启动编辑的 ContextMenu。它绑定(bind)到 View 模型中设置 IsEditingDescription 属性的命令。项目模板的样式使其在 IsEditingDescription 为 false 时在 TextBlockTextBox 中显示 Description > 当 IsEditingDescription 为真时。 Description 上的 setter 在设置描述后将 IsEditingDescription 设置为 false。

这非常有效。但是有些它应该做但没有做的事情:

  • 用户应该能够通过按 F2 启动编辑。
  • 用户应该能够通过按 ESC 键取消编辑。
  • 用户应该能够通过按 ENTER 键确认编辑。
  • 当用户第二次点击当前选定的项目时,应该启动编辑。
  • 出现文本框时应选择描述的文本

我想我可以使用命令和键绑定(bind)来处理前三项,尽管我还不太了解如何进行键绑定(bind)。但我真的想不出一种 MVVMish 的方式来做其他两个。有吗?

最佳答案

这是我不得不反复做的事情,所以我决定扩展 ListView 控件并添加 ItemKeyDown、ItemKeyUp 和 ItemDoubleClick 事件,当 ListView 中的项目处于焦点时,这些事件将被触发。 ListView 派生自 ListBox,因此您应该能够非常轻松地移植它。

/Fx/ListView.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Controls;

namespace Fx
{
public static class Func
{
/// <summary>
/// Finds a specific type of parent up the visual tree.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="dep"></param>
/// <returns></returns>
public static T FindParent<T>(this object obj)
{
DependencyObject dep = obj as DependencyObject;
while ((dep != null) && !(dep is T))
{
dep = VisualTreeHelper.GetParent(dep);
}
return (dep != null) ? (T)Convert.ChangeType(dep, typeof(T)) : default(T);
}
}

public class ListView:System.Windows.Controls.ListView
{

#region public event KeyboardEventHandler ItemKeyDown;
/// <summary>
/// Occurs when a key is pressed when a ListViewItem in this
/// ListView is in focus.
/// </summary>
public event KeyEventHandler ItemKeyDown;

/// <summary>
/// Raises the ItemKeyDown event for a ListViewitem in this ListView.
/// </summary>
/// <param name="item"></param>
/// <param name="e"></param>
public void OnItemKeyDown(ListViewItem item, KeyEventArgs e)
{
if (ItemKeyDown != null)
ItemKeyDown(item, e);
}

/// <summary>
/// Handle they KeyDown event on the ListView, find the related
/// ListViewItem and raise the ItemKeyDown event respectively.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ListView_KeyDown(object sender, KeyEventArgs e)
{
ListViewItem item = Func.FindParent<ListViewItem>(e.OriginalSource);
if (item != null)
OnItemKeyDown(item, e);
}
#endregion

#region public event KeyboardEventHandler ItemKeyUp;
/// <summary>
/// Occurs when a key is released when a ListViewItem in this
/// ListView is in focus.
/// </summary>
public event KeyEventHandler ItemKeyUp;

/// <summary>
/// Raises the ItemKeyUp event for a ListViewitem in this ListView.
/// </summary>
/// <param name="item"></param>
/// <param name="e"></param>
public void OnItemKeyUp(ListViewItem item, KeyEventArgs e)
{
if (ItemKeyUp != null)
ItemKeyUp(item, e);
}

/// <summary>
/// Handle they KeyUp event on the ListView, find the related
/// ListViewItem and raise the ItemKeyUp event respectively.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ListView_KeyUp(object sender, KeyEventArgs e)
{
ListViewItem item = Func.FindParent<ListViewItem>(e.OriginalSource);
if (item != null)
OnItemKeyUp(item, e);
}
#endregion

#region public event MouseButtonEventHandler ItemDoubleClick;
/// <summary>
/// Occurs when a ListViewItem in this Listview is double clicked.
/// </summary>
public event MouseButtonEventHandler ItemDoubleClick;

/// <summary>
/// Raise the ItemDoubleClick event for a ListViewItem.
/// </summary>
/// <param name="item"></param>
/// <param name="e"></param>
public void OnItemDoubleClick(ListViewItem item, MouseButtonEventArgs e)
{
if (ItemDoubleClick != null)
ItemDoubleClick(item, e);
}

/// <summary>
/// Handle the MouseDoubleClick event for the ListView, find the related
/// ListViewItem and raise the ItemDoubleClick event respectively.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ListView_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
ListViewItem item = Func.FindParent<ListViewItem>(e.OriginalSource);
if (item != null)
OnItemDoubleClick(item, e);
}
#endregion

public ListView()
{
MouseDoubleClick += new MouseButtonEventHandler(ListView_MouseDoubleClick);
KeyDown += new KeyEventHandler(ListView_KeyDown);
KeyUp += new KeyEventHandler(ListView_KeyUp);
}
}
}

现在使用它.../Pages/EmployeesPage.xaml

<UserControl x:Class="TestApp.Pages.EmployeesPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:fx="clr-namespace:Fx"
Width="800" Height="450">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="300" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<TextBlock Text="List Items" FontWeight="Bold" FontSize="18" />

<!-- here is the main part -->
<fx:ListView x:Name="EmployeesList" ItemDoubleClick="EmployeesList_ItemDoubleClick" ItemKeyDown="EmployeesList_ItemKeyDown" />
<!-- main part ends here -->

</StackPanel>
</Grid>
</UserControl>

/Pages/EmployeesPage.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace TestApp.Pages
{
/// <summary>
/// Interaction logic for EmployeesPage.xaml
/// </summary>
public partial class EmployeesPage : UserControl
{
public EmployeesPage()
{
InitializeComponent();

// Fill the ListView with data...
// EmployeesList.ItemsSource = SomeObservableCollectionOrDataSource
}

private void EmployeesList_ItemDoubleClick(object sender, MouseButtonEventArgs e)
{
MessageBox.Show("an item was double clicked");

ListViewItem item = sender as ListViewItem;
// entityType obj = item.DataContext as entityType

// you can begin editing here
}

private void EmployeesList_ItemKeyDown(object sender, KeyEventArgs e)
{
MessageBox.Show(e.Key.ToString() + " key was pressed on an item");

ListViewItem item = sender as ListViewItem;
// entityType obj = item.DataContext as entityType

if (e.Key == Key.F2)
{
// begin editing here
}
else if (e.Key == Key.Enter)
{
// end editing here
}
else if (e.Key == Key.Escape)
{
// cancel editing here
}
}
}
}

希望这至少对您有用。祝您好运。

关于wpf - 我如何(完全)在 ListBox 中实现就地编辑?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6923851/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com