我正在构建一个应用程序,其中ListBox
正在显示其项目的Description
属性。我想实现与Windows资源管理器中编辑文件名时相同的编辑就地功能,我发现这是一项非常多的工作。
到目前为止我所拥有的是一个ContextMenu
来启动编辑。它绑定到视图模型中设置IsEditingDescription
属性的命令。对项目模板进行样式设置,以便Description
在TextBlock
为假时显示IsEditingDescription
,在TextBox
为IsEditingDescription
时显示Description
。设置说明后,IsEditingDescription
上的设置器将{{1}}设置为false。
这非常有效。但有些事情并没有做到这一点:
我认为我可以使用命令和键绑定处理前三项,但我还不知道如何进行键绑定。但我真的无法找到MVVMish的方法去做其他两个。有吗?
答案 0 :(得分:2)
这是我不得不反复做的事情所以我决定扩展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
}
}
}
}
希望这至少对你有用..祝你好运。
答案 1 :(得分:0)
至于确保在进入编辑模式时选择文本,我之前使用了以下附加到我的另一个项目中的文本框的行为。它在VB中,但应该非常简单。
Public Class SelectAllOnFocusTextboxBehavior
Inherits Behavior(Of TextBox)
Protected Overrides Sub OnAttached()
MyBase.OnAttached()
AddHandler AssociatedObject.GotKeyboardFocus, AddressOf AssociatedObjectGotKeyboardFocus
End Sub
Protected Overrides Sub OnDetaching()
MyBase.OnDetaching()
RemoveHandler AssociatedObject.GotKeyboardFocus, AddressOf AssociatedObjectGotKeyboardFocus
End Sub
Private Sub AssociatedObjectGotKeyboardFocus(ByVal sender As Object, ByVal e As KeyboardFocusChangedEventArgs)
AssociatedObject.SelectAll()
End Sub
End Class