我正在实施一种重命名window.onkeydown=function(e){
if(e.keycode==34 || e.keycode==32){
e.preventDefault();
}
}
中元素的方法。我的想法不是建立一个特殊的treeview
,而是一个特殊的TreeView
,它也可以在Label
和其他控件中使用。它通过点击将焦点设置为自身,因此我将ListBox
更改为Focusable
。如果专注,可以通过 [F2] 进行编辑,并在已经拥有焦点时点击它。可编辑的意思是一个文本框显示(所有类似于Windows资源管理器)。不幸的是,当我点击true
时,TreeViewItem
没有被选中。单击左侧的图标时,会选择label
。
我没有处理任何事件设置TreeViewItem
,但我认为Handled=true
本身会处理点击,因此Label
没有机会对其做出反应。如果我就在这里,有没有办法以一种它根本不处理事件的方式修改标签(自己的类?)?
答案 0 :(得分:0)
我重新考虑了我的尝试。解决方案根本不是重点。相反,我将处理程序绑定到当前具有焦点的观察元素的KeyUp
事件(请参阅EditableLabel.cs
中的注释)。
EditableLabel.xaml:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:myown.Wpf"
xmlns:localCtrls="clr-namespace:myown.Wpf.Controls">
<Style TargetType="{x:Type localCtrls:EditableLabel}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type localCtrls:EditableLabel}">
<StackPanel>
<Label x:Name="label"
Content="{TemplateBinding Text}"
Visibility="Visible"
Height="{TemplateBinding Height}"
Width="{TemplateBinding Width}"
Padding="{TemplateBinding Padding}"
Foreground="{TemplateBinding Foreground}"/>
<!-- TemplateBinding is always OneWay! -->
<TextBox x:Name="textbox"
Text="{Binding Path=Text, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
Visibility="Collapsed"
Height="{TemplateBinding Height}"
Width="{TemplateBinding Width}"
Padding="{TemplateBinding Padding}"/>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
EditableLabel.cs:
public partial class EditableLabel : Label
{
#region DependencyProperties
public static readonly DependencyProperty IsEditingProperty =
DependencyProperty.Register("IsEditing", typeof(bool), typeof(EditableLabel),
new UIPropertyMetadata(false, IsEditingUpdate));
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text", typeof(string), typeof(EditableLabel),
new FrameworkPropertyMetadata("",
FrameworkPropertyMetadataOptions.AffectsRender |
FrameworkPropertyMetadataOptions.AffectsParentMeasure |
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
public bool IsEditing
{
get { return (bool)GetValue(IsEditingProperty); }
set { SetValue(IsEditingProperty, value); }
}
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
private string m_lastValue = "";
private IInputElement m_lastFocus = null;
private Label m_label = null;
private TextBox m_textBox = null;
#endregion
static EditableLabel()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(EditableLabel),
new FrameworkPropertyMetadata(typeof(EditableLabel)));
}
public EditableLabel()
{
LostFocus += (s, e) => { };
LostKeyboardFocus += EditableLabel_LostKeyboardFocus;
}
private void EditableLabel_LostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
if (e.NewFocus != null)
Debug.WriteLine(e.NewFocus.GetType().Name);
}
public override void OnApplyTemplate()
{
m_label = GetTemplateChild("label") as Label;
m_textBox = GetTemplateChild("textbox") as TextBox;
m_label.MouseUp += Label_MouseUp;
m_textBox.LostFocus += (s, e) => IsEditing = false;
m_textBox.KeyUp += (s, e) => { TextBox_KeyUp(s, e); e.Handled = true; };
m_textBox.GotKeyboardFocus += (s, e) => m_textBox.SelectAll();
base.OnApplyTemplate();
}
private void Label_MouseUp(object sender, MouseButtonEventArgs e)
{
DependencyObject scope = FocusManager.GetFocusScope(this);
IInputElement currFocus = FocusManager.GetFocusedElement(scope);
if ((currFocus != null))
{
if (currFocus == m_lastFocus)
{
IsEditing = true;
}
else
{
m_lastFocus = currFocus;
DependencyObject observedObject = currFocus as DependencyObject;
if (observedObject != null)
{
m_lastFocus.LostKeyboardFocus += ObservedElementLostFocus;
m_lastFocus.KeyUp += ObservedElement_KeyUp; // THIS IS THE TRICK
}
}
}
}
private void ObservedElement_KeyUp(object sender, KeyEventArgs e)
{
if (e.Key == Key.F2)
{
IsEditing = true;
e.Handled = true;
}
}
private void ObservedElementLostFocus(object sender, RoutedEventArgs e)
{
KeyboardFocusChangedEventArgs kfc = e as KeyboardFocusChangedEventArgs;
if (kfc.NewFocus != null)
{
if ((kfc.NewFocus != m_textBox) && (kfc.NewFocus != m_lastFocus))
{
m_lastFocus.LostKeyboardFocus -= ObservedElementLostFocus;
m_lastFocus.KeyUp -= ObservedElement_KeyUp;
m_lastFocus = null;
}
}
}
private void TextBox_KeyUp(object sender, KeyEventArgs e)
{
if (e.Key == Key.Escape)
{
IsEditing = false;
Text = m_lastValue;
}
else if (e.Key == Key.Enter)
{
IsEditing = false;
}
}
private static void IsEditingUpdate(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
EditableLabel self = obj as EditableLabel;
if ((bool)e.NewValue)
{
self.m_lastValue = self.Text;
self.m_textBox.Visibility = Visibility.Visible;
self.m_textBox.Focus();
self.m_label.Visibility = Visibility.Collapsed;
}
else
{
self.m_textBox.Visibility = Visibility.Collapsed;
self.m_label.Visibility = Visibility.Visible;
if (self.m_lastFocus != null)
self.m_lastFocus.Focus();
}
}
}