我如何知道已显示Silverlight控件?

时间:2011-05-16 10:37:55

标签: c# silverlight listbox

我有一个列表框,显示可以添加的帮助主题的名称以及更改的主题的名称。最初它只是显示字符串,但为了使内联编辑工作,我将其更改为使用由字符串和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;
}

1 个答案:

答案 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();
    }
}
相关问题