我有一個WPF ComboBox
,它的IsEditable
屬性綁定到可以打開和關閉它的視圖模型。當它打開時,我想要關注ComboBox
並選擇編輯TextBox
中的所有文本。WPF:選擇所有文本並將焦點設置爲ComboBox的可編輯文本框
我看不出最好的做法。我應該替換ControlTemplate
,繼承ComboBox
基類,並提供所需的屬性,使用附加屬性還是其他方法?
我有一個WPF ComboBox
,它的IsEditable
屬性綁定到可以打開和關閉它的視圖模型。當它打開時,我想要關注ComboBox
並選擇編輯TextBox
中的所有文本。WPF:選擇所有文本並將焦點設置爲ComboBox的可編輯文本框
我看不出最好的做法。我應該替換ControlTemplate
,繼承ComboBox
基類,並提供所需的屬性,使用附加屬性還是其他方法?
我有一個解決方案給你。
我正在使用Model-View-ViewModel和附加屬性方法的組合。
首先,你需要知道MVVM的消息系統這個工作,也知道你的命令。因此,從附加屬性開始,我們開始將IsFocused事件設置爲我們希望關注的組合框,並選擇所有文本。
#region Select On Focus
public static bool GetSelectWhenFocused(DependencyObject obj)
{
return (bool)obj.GetValue(SelectWhenFocusedProperty);
}
public static void SetSelectWhenFocused(DependencyObject obj, bool value)
{
obj.SetValue(SelectWhenFocusedProperty, value);
}
// Using a DependencyProperty as the backing store for SelectWhenFocused. This enables animation, styling, binding, etc...
public static read-only DependencyProperty SelectWhenFocusedProperty =
DependencyProperty.RegisterAttached("SelectWhenFocused", typeof(bool), typeof(EditableComboBox), new UIPropertyMetadata(OnSelectOnFocusedChanged));
public static void OnSelectOnFocusedChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
bool SetProperty = (bool)args.NewValue;
var comboBox = obj as ComboBox;
if (comboBox == null) return;
if (SetProperty)
{
comboBox.GotFocus += GotFocused;
Messenger.Default.Register<ComboBox>(comboBox, Focus);
}
else
{
comboBox.GotFocus -= GotFocused;
Messenger.Default.Unregister<ComboBox>(comboBox, Focus);
}
}
public static void GotFocused(object sender, RoutedEventArgs e)
{
var comboBox = sender as ComboBox;
if(comboBox == null) return;
var textBox = comboBox.FindChild(typeof(TextBox), "PART_EditableTextBox") as TextBox;
if (textBox == null) return;
textBox.SelectAll();
}
public static void Focus(ComboBox comboBox)
{
if(comboBox == null) return;
comboBox.Focus();
}
#endregion
這段代碼顯示的是當我們設置附加屬性SelectWhenFocused真,它將註冊到監聽GotFocused事件和選擇中的所有文本。
要使用很簡單:
<ComboBox
IsEditable="True"
ComboBoxHelper:EditableComboBox.SelectWhenFocused="True"
x:Name="EditBox" />
現在我們需要一個按鈕,點擊時,將設置重點組合框。
<Button
Command="{Binding Focus}"
CommandParameter="{Binding ElementName=EditBox}"
Grid.Column="1" >Focus</Button>
通知的CommandParameter如何被它的名字編輯框綁定到ComboBox。這是當命令執行時,只有這個組合框變得焦點和所有文本被選中。
在我的ViewModel,我宣佈爲繼焦點命令:
public SimpleCommand Focus { get; set; }
public WindowVM()
{
Focus = new SimpleCommand {ExecuteDelegate = x => Broadcast(x as ComboBox)};
}
這是一個測試和驗證的技術,爲我的作品。我希望這不是針對您的問題的矯枉過正的解決方案。祝你好運。
謝謝,三。我已經實現了這種模式,但我注意到ComboBox上沒有FindChild方法。 – codekaizen 2010-01-28 02:22:49
我的歉意,FindChild在這裏:http://stackoverflow.com/questions/636383/wpf-ways-to-find-controls/1501391#1501391 – 2010-01-28 02:24:54
謝謝,三。在我想了一下之後,我猜想了實現。看起來我非常接近。但是,找不到TextBox子項,原因很可能是我更改了ComboBox的IsEditable屬性的複雜因素,並且在處理GotFocused事件時,ComboBox控件模板尚未更改,而且TextBox沒有被創建。任何有關如何推遲搜索直到控制模板應用後的見解? – codekaizen 2010-01-28 02:34:23