2009-07-20 45 views
1

在我的WPF應用程序中,我有一個數據綁定TextBox和一個數據綁定ItemsControlItemsControl的內容取決於TextBox的內容。我希望能夠在TextBox中鍵入一個值,然後按Tab鍵並輸入ItemsControl中的第一項(由TextBox中的值創建)。我遇到的問題是在WPF在ItemsControl中創建模板項目之前評估選項卡操作。下面的代碼演示了此問題:WPF Tab Into Databound ItemsControl

<Window x:Class="BindingExample.Window1" x:Name="SelfControl" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:loc="clr-namespace:BindingExample" Title="Window1" Height="300" Width="400"> 
    <Window.Resources> 
     <DataTemplate DataType="{x:Type loc:ChildClass}"> 
      <TextBox Text="{Binding Value}" /> 
     </DataTemplate> 
    </Window.Resources> 
    <StackPanel DataContext="{Binding ElementName=SelfControl}" Focusable="False"> 
     <Label Content="Options: A, B, C" /> 
     <TextBox Text="{Binding Object.Value}" /> 
     <ItemsControl Margin="16,0,0,0" ItemsSource="{Binding Object.Children}" Focusable="False"> 
      <ItemsControl.ItemsPanel> 
       <ItemsPanelTemplate> 
        <StackPanel Orientation="Horizontal" /> 
       </ItemsPanelTemplate> 
      </ItemsControl.ItemsPanel> 
     </ItemsControl> 
     <TextBox Text="Box2" /> 
    </StackPanel> 
</Window> 

using System.Collections.Generic; 
using System.ComponentModel; 
using System.Windows; 

namespace BindingExample 
{ 
    public partial class Window1 
    { 
     public static readonly DependencyProperty ObjectProperty = DependencyProperty.Register("Object", typeof(ParentClass), typeof(Window1)); 
     public ParentClass Object 
     { 
      get { return GetValue(ObjectProperty) as ParentClass; } 
      set { SetValue(ObjectProperty, value); } 
     } 

     public Window1() 
     { 
      InitializeComponent(); 
      Object = new ParentClass(); 
     } 
    } 

    public class ParentClass : INotifyPropertyChanged 
    { 
     private string value; 
     public string Value 
     { 
      get { return value; } 
      set { this.value = value; if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("Children")); } 
     } 

     public IEnumerable<ChildClass> Children 
     { 
      get 
      { 
       switch (Value.ToUpper()) 
       { 
        case "A": return new ChildClass[] { "A-1", "A-2", "A-2" }; 
        case "B": return new ChildClass[] { "B-1", "B-2", "B-3" }; 
        case "C": return new ChildClass[] { "C-1", "C-2", "C-2" }; 
        default: return new ChildClass[] { "Unknown" }; 
       } 
      } 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 
    } 

    public class ChildClass 
    { 
     public string Value { get; set; } 
     public static implicit operator ChildClass(string value) { return new ChildClass { Value = value }; } 
    } 
} 

在這段代碼中,我想輸入「A」到第一TextBox,按Tab鍵,並有重點轉移到孩子TextBox文本「A-1」。相反,焦點跳轉到文本框「文本2」。我如何實現我在這裏尋找的行爲?

注:作爲朱利安波林所指出的,可以通過對TextBoxPropertyChanged切換UpdateSourceTrigger,使這項工作。然而,這隻適用於「如鍵入」綁定的情況。在我的情況下,我還想通過一次按鍵來設置值和標籤。有沒有辦法強制ItemsControl按需創建其模板化項目?

回答

1

嘗試設置TextBoxPropertyChanged所以底層的值設置當你輸入一個新值,而不是當TextBox失去焦點的UpdateMode

<TextBox Text="{Binding Path=Object.Value, UpdateMode=PropertyChanged}" /> 
+0

This works。然而,理想情況下,我希望在控件失去焦點時發生綁定,而不是在用戶輸入時發生。 – 2009-07-20 22:51:29

0

這裏是一個替代的解決方案。這有點破解,但似乎工作。由於ItemsControl中的模板對象直到主線程執行暫停時纔會創建,因此此代碼將捕獲該選項卡,更新綁定並設置一個定時器,以便在有可能創建項目時移動焦點。

... 
<TextBox Text="{Binding Object.Value}" KeyDown="TextBox_KeyDown" /> 
... 

public partial class Window1 
{ 
    private DispatcherTimer timer; 

    ... 

    private void TextBox_KeyDown(object sender, KeyEventArgs e) 
    { 
     if (e.Key == Key.Tab && e.KeyboardDevice.Modifiers != ModifierKeys.Shift) 
     { 
      e.Handled = true; 
      var textbox = (TextBox)sender; 
      textbox.GetBindingExpression(TextBox.TextProperty).UpdateSource(); 
      (timer = new DispatcherTimer(
       new TimeSpan(100000), // 10 ms 
       DispatcherPriority.Normal, 
       delegate 
       { 
        textbox.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next)); 
        timer.Stop(); 
       }, Dispatcher)).Start(); 
     } 
    } 
} 

我這個代碼中看到的唯一的問題是,ItemsControl可能需要更長的時間超過10毫秒來填充,在這種情況下,Tab鍵將跳過這些項目。是否有任何方法檢測ItemsControl項目的創建是否已經發生?