我有一個列表框,顯示可添加的幫助主題的名稱以及更改的主題的名稱。本來這只是顯示的字符串,但要獲得行內編輯工作,我改變了它使用由字符串的自定義類型和InEdit
屬性,以便用戶界面可以判斷是否顯示TextBlock
或TextBox
:我如何知道已經顯示Silverlight控件?
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
implemetation。
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 { ... }
}
+1克里斯,這個(http://stackoverflow.com/questions/124649/how-do-我給了一個textbox-focus-in-silverlight)解決了長時間運行的頭痛問題:) – Town 2011-05-16 14:05:12