如何知道已显示 Silverlight 控件
本文关键字:Silverlight 控件 显示 何知道 | 更新日期: 2023-09-27 17:56:48
我有一个列表框,显示可以添加到的帮助主题的名称以及更改的主题的名称。最初它只是显示字符串,但为了让内联编辑工作,我将其更改为使用由字符串和InEdit
属性组成的自定义类型,以便 UI 可以确定是显示TextBlock
还是TextBox
:
XAML:
<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
方法添加了一个事件,我在视图中处理了该事件,但同样在TextBox
可见之前触发了该事件。
下面是支持上述 XAML 的代码。我试图削减它,但似乎仍然有很多,所以如果你不感兴趣,你可以跳过这个;)
代码隐藏:
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;
}
定义:
public class EditableHelpTopic : INotifyPropertyChanged
{
public bool InEdit { ... }
public string Description { ... }
}
事实证明,它比我想象的要简单。
我只需要向TextBox
添加一个Loaded
事件处理程序:
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();
}
}