我有一个列表框,显示可以添加的帮助主题的名称以及更改的主题的名称。最初它只是显示字符串,但为了使内联编辑工作,我将其更改为使用由字符串和InEdit
属性组成的自定义类型,以便UI可以确定是否显示TextBlock
或{ {1}}:
XAML:
TextBox
<ListBox ItemsSource="{Binding HelpTopics, Mode=TwoWay}"
SelectedValuePath="Description"
SelectedValue="{Binding SelectedPageId, Mode=TwoWay}"
SelectionChanged="ListBox_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<TextBlock Text="{Binding Description, Mode=TwoWay}"
VerticalAlignment="Center"
MouseLeftButtonUp="TopicTextBlock_MouseLeftButtonUp"
Visibility="{Binding InEdit, Converter={StaticResource boolToVisibilityConverter}, ConverterParameter=contra}"/>
<TextBox Text="{Binding Description, Mode=TwoWay}"
Visibility="{Binding InEdit, Converter={StaticResource boolToVisibilityConverter}, ConverterParameter=pro}"
LostFocus="EditTopicTextBox_LostFocus"
HorizontalAlignment="Stretch" VerticalAlignment="Center"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button Margin="5" Content="Add Topic" Command="{Binding AddTopicCommand}"/>
是HelpTopics
ObservableCollection<EditableHelpTopic>
是SelectedPageId
string
是一个完成其所说内容的转换器。
什么有效:
boolToVisibilityConverter
并选择所有文本以便覆盖。TextBox
失去焦点时,会保存编辑内容,并且显示屏会返回TextBox
。什么行不通:
TextBlock
应该具有焦点并选择文本,以便用户输入新名称。 所以我的问题是代码或事件中有一点我知道TextBox
已经创建并且可见,所以我可以设置焦点并选择其内容。我已经尝试挂钩TextBox
事件,但是当它触发时,SelectionChanged
尚未显示。我还在视图模型中为TextBox
方法添加了一个事件,我在视图中处理了该事件,但在OnAddTopicExecute
可见之前再次触发了该事件。
以下是支持上述XAML的代码。我试图减少它,但似乎仍有很多,所以你可以跳过这个,如果你不感兴趣;)
代码背后:
TextBox
查看型号:
private DateTime lastClickTime = DateTime.MinValue;
private Point lastClickPosition;
private void TopicTextBlock_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
UIElement element = sender as UIElement;
if ((DateTime.Now - this.lastClickTime).TotalMilliseconds > 300)
{
this.lastClickPosition = e.GetPosition(element);
this.lastClickTime = DateTime.Now;
}
else
{
Point position = e.GetPosition(element);
if (Math.Abs(this.lastClickPosition.X - position.X) < 4 && Math.Abs(this.lastClickPosition.Y - position.Y) < 4)
{
var textBlock = sender as TextBlock;
var editableHelpTopic = textBlock.DataContext as EditableHelpTopic;
editableHelpTopic.InEdit = true;
var parent = textBlock.Parent as Grid;
TextBox textBox = parent.Children.First(c => c.GetType() == typeof(TextBox)) as TextBox;
textBox.Focus();
textBox.SelectAll();
}
}
}
private void EditTopicTextBox_LostFocus(object sender, RoutedEventArgs e)
{
var textBox = sender as TextBox;
var editableHelpTopic = textBox.DataContext as EditableHelpTopic;
editableHelpTopic.InEdit = false;
if (!textBox.Text.Equals(editableHelpTopic.Description))
{
this.editViewModel.RenameTopic(textBox.Text);
}
}
其中public EditViewModel()
{
...
this.AddTopicCommand = new DelegateCommand(this.OnAddTopicExecute, this.OnAddTopicCanExecute);
...
}
是DelegateCommand
的实现。
ICommand
说明:
private void OnAddTopicExecute(object parameter)
{
var newTopic = new EditableHelpTopic
{
Description = "NewTopic",
InEdit = true
};
this.HelpTopics.Add(newTopic);
this.SelectedPageId = newTopic.Description;
}
答案 0 :(得分:3)
事实证明这比我想象的要简单。
我只需要向Loaded
添加TextBox
事件处理程序:
private void EditTopicTextBox_Loaded(object sender, RoutedEventArgs e)
{
var textBox = sender as TextBox;
var editableHelpTopic = textBox.DataContext as EditableHelpTopic;
if (editableHelpTopic.InEdit)
{
textBox.Focus();
textBox.SelectAll();
}
}