在 WPF 中丢失焦点事件时更改列表框模板 [英] Change listbox template on lost focus event in WPF
问题描述
我想显示一个带有 TextBlocks 作为项目的列表框.当用户单击/选择一个项目时,它会更改为用于编辑的 TextBox.一旦控件失去焦点,项目就会变回 TextBlock.
以下 XAML 几乎可以正常工作,因为 TextBlock 在被选中时确实会变成一个 TextBox.如果我选择列表中的另一个项目,它也会变回 TextBlock.问题是,如果我移出列表框(在本例中为添加新文本框),列表项将保持为文本框.
问题( WPF ListViewItem 失去焦点活动 - 如何参加活动? )看起来很有希望,但我无法让它发挥作用.我尝试使用 IsFocused 属性,但后来我无法编辑文本框,因为当我进入文本框时,listboxitem 会失去焦点,从而在我有机会编辑文本之前返回到 TextBlock.>
如果列表框/项目失去焦点,如何让 TextBox 转回 TextBlock?
(也欢迎任何其他实现目标的实现)
<窗口.资源><DataTemplate x:Key="ItemTemplate"><TextBlock Text="{绑定名称}"/></数据模板><DataTemplate x:Key="SelectedTemplate"><TextBox Text="{Binding Name, Mode=TwoWay}"/></数据模板><Style TargetType="{x:Type ListBoxItem}" x:Key="ContainerStyle"><Setter Property="ContentTemplate" Value="{StaticResource ItemTemplate}"/><Style.Triggers><Trigger Property="IsSelected" Value="True"><Setter Property="ContentTemplate" Value="{StaticResource SelectedTemplate}"/></触发器></Style.Triggers></风格></Window.Resources><堆栈面板><ListBox ItemsSource="{绑定部门}" HorizontalContentAlignment="Stretch"ItemContainerStyle="{StaticResource ContainerStyle}"/><网格><Grid.ColumnDefinitions><ColumnDefinition Width="*"/><ColumnDefinition Width="Auto"/></Grid.ColumnDefinitions><TextBox Text="{Binding NewDepartmentName, Mode=TwoWay}"/><Button Grid.Column="1" Width="50" Content="Add" Command="{Binding Path=AddNewDepartmentCommand}"/></网格></StackPanel></窗口>
这不能回答您的问题,而是通过在未选择 listboxitem 时使文本框看起来像文本块来提供替代解决方案:
<资源字典><Style x:Key="ListBoxSelectableTextBox" TargetType="{x:Type TextBox}"><Setter Property="IsHitTestVisible" Value="False"/><Style.Triggers><DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}, AncestorLevel=1}}" Value="True"><Setter Property="IsHitTestVisible" Value="True"/></数据触发器></Style.Triggers></风格></ResourceDictionary></Page.Resources><网格><ListBox ItemsSource="{绑定部门}" HorizontalContentAlignment="Stretch"><ListBox.ItemTemplate><数据模板><TextBox Margin="5" Style="{StaticResource ListBoxSelectableTextBox}" Text="{Binding Name}" BorderBrush="{x:Null}"/></数据模板></ListBox.ItemTemplate></列表框></网格>
I want to present a listbox with TextBlocks as items. When the user clicks/selects an item it changes into a TextBox for editing. As soon as the controls loses focus the item would turn back to a TextBlock.
The following XAML is almost working in that the TextBlock does turn into a TextBox when it's selected. It also turns back to a TextBlock if I select another item on the list. The problem is that if I move out of the listbox (in this case to the Add New text box) the list item stays as a TextBox.
The question ( WPF ListViewItem lost focus event - How to get at the event? ) looked promising but I can't make it work. I tried using the IsFocused property but then I wasn't able to edit the textbox because when I got into the textbox the listboxitem would go out of focus and thus turning back to a TextBlock before I had a chance to edit the text.
How can I make the TextBox turn back to TextBlock if the listbox/item loses the focus?
(Any other implementation that accomplishes the goal are also welcomed)
<Window x:Class="MyView.MainWindow1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
Title="MainWindow1" Height="300" Width="200">
<Window.Resources>
<DataTemplate x:Key="ItemTemplate">
<TextBlock Text="{Binding Name}" />
</DataTemplate>
<DataTemplate x:Key="SelectedTemplate">
<TextBox Text="{Binding Name, Mode=TwoWay}" />
</DataTemplate>
<Style TargetType="{x:Type ListBoxItem}" x:Key="ContainerStyle">
<Setter Property="ContentTemplate" Value="{StaticResource ItemTemplate}" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="ContentTemplate" Value="{StaticResource SelectedTemplate}" />
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<StackPanel >
<ListBox ItemsSource="{Binding Departments}" HorizontalContentAlignment="Stretch"
ItemContainerStyle="{StaticResource ContainerStyle}" />
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBox Text="{Binding NewDepartmentName, Mode=TwoWay}" />
<Button Grid.Column="1" Width="50" Content="Add" Command="{Binding Path=AddNewDepartmentCommand}" />
</Grid>
</StackPanel>
</Window>
This doesn't answer your question, but gives an alternative solution by making a textbox look like a textblock when the listboxitem isn't selected:
<Page.Resources>
<ResourceDictionary>
<Style x:Key="ListBoxSelectableTextBox" TargetType="{x:Type TextBox}">
<Setter Property="IsHitTestVisible" Value="False" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}, AncestorLevel=1}}" Value="True">
<Setter Property="IsHitTestVisible" Value="True" />
</DataTrigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
</Page.Resources>
<Grid>
<ListBox ItemsSource="{Binding Departments}" HorizontalContentAlignment="Stretch">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBox Margin="5" Style="{StaticResource ListBoxSelectableTextBox}" Text="{Binding Name}" BorderBrush="{x:Null}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
这篇关于在 WPF 中丢失焦点事件时更改列表框模板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!