もう1つの方法は、表示用のTextBlockと編集用の非表示のTextBoxです。 TextBoxが隠されている間に入力フォーカスを取得しないので、キーボードイベントを受け取るTreeViewでF2を聞きます。 F2キーを押すと、TextBlockを非表示にしてTextBoxを編集用に表示します。 TextBoxを非表示にしてTextBlockを再度表示するには、TextBoxのLostFocusイベントを処理します。
このようにすることの利点の1つは、偽 TextBoxをTextBlockのように見て動作させることです。 TextBlockは常にTextBlockのように見え、動作し、TextBoxは常にTextBoxのように見え、動作し、より高いリソースレベルで適用されたすべてのスタイルを継承することができます。
編集:サンプルコードを追加してください。
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は、データオブジェクトの基本クラスである前提としています:
ここ
<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>
が背後にあるコードである:ここでは
はXAMLです
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;
}
}
解決策が見つかりました。私はまだどこでもこれを見つけることができなかったことに驚いています。 バインディングを使用している場合は、GotFocusまたはPreviewMouseLeftButtonDownイベントを処理し、送信者をTextBoxとしてローカルオブジェクトにキャストします。そこから、テキストボックスオブジェクトのDataContextメンバにアクセスできます。これは、TreeViewItemにバインドされたデータオブジェクトを表します。 – Josh