另一种方法是有一个 TextBlock 用于显示和一个隐藏的 TextBox 用于编辑。在将接收键盘事件的 TreeView 上侦听 F2,因为 TextBox 在隐藏时不会获得任何输入焦点。按下 F2 时,隐藏 TextBlock 并显示 TextBox 进行编辑。处理 TextBox 上的 LostFocus 事件,隐藏 TextBox 并再次显示 TextBlock。
这样做的一个好处是您不必伪造 TextBox 使其看起来和表现得像一个TextBlock。 TextBlock 的外观和行为始终与 TextBlock 相似,TextBox 的外观和行为始终与 TextBox 相似,并且它们都可以继承在更高资源级别应用的任何样式。
编辑:添加一些示例代码。
这是 XAML:
<Window.Resources>
<Style x:Key="TreeViewTextBlockStyle" TargetType="TextBlock">
<Setter Property="Text" Value="{Binding DisplayText}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding InEditMode}" Value="true">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
<Style x:Key="TreeViewTextBoxStyle" TargetType="TextBox">
<Setter Property="Text" Value="{Binding DisplayText, Mode=TwoWay}"/>
<Setter Property="MinWidth" Value="50"/>
<EventSetter Event="LostFocus" Handler="TreeViewTextBox_LostFocus" />
<Style.Triggers>
<DataTrigger Binding="{Binding InEditMode}" Value="false">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
<DataTrigger Binding="{Binding InEditMode}" Value="true">
<Setter Property="FocusManager.FocusedElement" Value="{Binding RelativeSource={RelativeSource Mode=Self}}"/>
</DataTrigger>
</Style.Triggers>
</Style>
<HierarchicalDataTemplate x:Key="HL7MessageTemplate" ItemsSource="{Binding Segments}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="[msg]--" FontWeight="Bold"/>
<TextBlock Style="{StaticResource TreeViewTextBlockStyle}"/>
<TextBox Style="{StaticResource TreeViewTextBoxStyle}" />
</StackPanel>
</HierarchicalDataTemplate>
<DataTemplate x:Key="HL7SegmentTemplate">
<StackPanel Orientation="Horizontal">
<TextBlock Text="[seg]--" FontWeight="Bold"/>
<TextBlock Style="{StaticResource TreeViewTextBlockStyle}"/>
<TextBox Style="{StaticResource TreeViewTextBoxStyle}" />
</StackPanel>
</DataTemplate>
<HierarchicalDataTemplate x:Key="HL7SegmentWithSubcomponentsTemplate" ItemsSource="{Binding Subcomponents}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="[seg+sub]--" FontWeight="Bold"/>
<TextBlock Style="{StaticResource TreeViewTextBlockStyle}"/>
<TextBox Style="{StaticResource TreeViewTextBoxStyle}" />
</StackPanel>
</HierarchicalDataTemplate>
<DataTemplate x:Key="HL7SubcomponentTemplate">
<StackPanel Orientation="Horizontal">
<TextBlock Text="[sub]--" FontWeight="Bold"/>
<TextBlock Style="{StaticResource TreeViewTextBlockStyle}"/>
<TextBox Style="{StaticResource TreeViewTextBoxStyle}" />
</StackPanel>
</DataTemplate>
<local:HL7DataTemplateSelector x:Key="HL7DataTemplateSelector"/>
</Window.Resources>
<Grid>
<TreeView Name="treeView1" ItemsSource="{Binding}" ItemTemplateSelector="{StaticResource HL7DataTemplateSelector}" KeyUp="treeView1_KeyUp"/>
</Grid>
下面是代码:
private void treeView1_KeyUp(object sender, KeyEventArgs e)
{
if (e.Key == Key.F2)
{
HL7Object selectedHL7Object = treeView1.SelectedItem as HL7Object;
if (selectedHL7Object != null)
{
selectedHL7Object.InEditMode = true;
}
}
}
private void TreeViewTextBox_LostFocus(object sender, RoutedEventArgs e)
{
HL7Object selectedHL7Object = treeView1.SelectedItem as HL7Object;
if (selectedHL7Object != null)
{
selectedHL7Object.InEditMode = false;
}
}
此代码假定您的 HL7Object 是数据对象的基类,如下所示:
public class HL7Object : INotifyPropertyChanged
{
private string DisplayTextField;
public string DisplayText
{
get { return this.DisplayTextField; }
set
{
if (this.DisplayTextField != value)
{
this.DisplayTextField = value;
this.OnPropertyChanged("DisplayText");
}
}
}
private bool InEditModeField = false;
public bool InEditMode
{
get { return this.InEditModeField; }
set
{
if (this.InEditModeField != value)
{
this.InEditModeField = value;
this.OnPropertyChanged("InEditMode");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
而且您还实现了一个 DataTemplateSelector,由于您的复杂要求,我假设您已经实现了它。如果没有,这里是一个例子:
public class HL7DataTemplateSelector : DataTemplateSelector
{
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
FrameworkElement element = container as FrameworkElement;
if (element != null && item != null &&
(item is HL7Message || item is HL7Segment || item is HL7Subcomponent)
)
{
HL7Message message = item as HL7Message;
if (message != null)
{
return element.FindResource("HL7MessageTemplate") as DataTemplate;
}
HL7Segment segment = item as HL7Segment;
if (segment != null)
{
if (segment.Subcomponents != null && segment.Subcomponents.Count > 0)
{
return element.FindResource("HL7SegmentWithSubcomponentsTemplate") as DataTemplate;
}
else
{
return element.FindResource("HL7SegmentTemplate") as DataTemplate;
}
}
HL7Subcomponent subcomponent = item as HL7Subcomponent;
if (subcomponent != null)
{
return element.FindResource("HL7SubcomponentTemplate") as DataTemplate;
}
}
return null;
}
}