2013-04-05 101 views
2

在tabcontrol上,我有幾個標籤頁,其中一個標籤頁上有一個文本框。WPF控件在單擊標籤時失去焦點

此文本框內容綁定了一個簡單的Path = PropertyName和UpdateSourceTrigger = LostFocus。我使用LostFocus的原因是我陷入了文本框的丟失焦點事件,並可能重新格式化文本。這是一個「時間」文本框,如果他們輸入「0900」,我想重新格式化爲「09:00」。當我按Tab鍵移動到下一個控件時,這部分工作得很好,但如果我鍵入「0900」,然後按其中一個其他選項卡,我擊中丟失的焦點並重新格式化文本框中的值,但綁定永遠不會被調用來更新我的對象。當我回到標籤頁時,該值被清空(或重置爲對象上的原始值)

任何想法爲什麼textbox在更改標籤頁時不會觸發Binding更新?

注意:這也會發生在連接到丟失焦點事件的常規文本框中。這似乎與點擊標籤有關。

[新增代碼]] 更多注意事項:1。 我動態創建的標籤(不知道這有什麼用它做與否) 2.我現在用的棱鏡上的標籤和控件庫

主窗口的XAML

<Window.Resources> 
    <DataTemplate DataType="{x:Type ctrls:myTextBoxDef}"> 
     <Grid Width="300"> 
      <Grid.ColumnDefinitions> 
       <ColumnDefinition Width="Auto" MinWidth="100" /> 
       <ColumnDefinition Width="*" /> 
      </Grid.ColumnDefinitions> 
      <Grid.RowDefinitions> 
       <RowDefinition Height="28" /> 
      </Grid.RowDefinitions> 
      <TextBlock Grid.Column="0" 
        HorizontalAlignment="Stretch" 
        VerticalAlignment="Center" 
        Text="{Binding LabelText}" /> 

      <TextBox Grid.Column="1" 
       HorizontalAlignment="Stretch" 
       VerticalAlignment="Center" 
       Text="{Binding DocValue, 
           Mode=TwoWay, 
           ValidatesOnDataErrors=True, 
           UpdateSourceTrigger=LostFocus}" 
         /> 
     </Grid> 
    </DataTemplate> 
</Window.Resources> 


<Grid> 
    <TabControl HorizontalAlignment="Stretch" 
       VerticalAlignment="Stretch" 
       HorizontalContentAlignment="Stretch" 
       VerticalContentAlignment="Stretch" 
       IsTabStop="False"     
       ItemsSource="{Binding Tabs, Mode=OneWay}" 
       SelectedItem="{Binding SelectedTab, 
           Mode=TwoWay, 
           NotifyOnSourceUpdated=True}" 
       > 
     <TabControl.ItemTemplate> 
      <DataTemplate> 
       <Grid> 
        <TextBlock Margin="18,14,22,0"          
           Text="{Binding HeaderText}" /> 
       </Grid> 
      </DataTemplate> 
     </TabControl.ItemTemplate> 
     <!-- Content --> 
     <TabControl.ContentTemplate> 
      <DataTemplate> 
       <Grid> 
        <Grid.ColumnDefinitions> 
         <ColumnDefinition Width="Auto" /> 
         <ColumnDefinition Width="Auto" /> 
        </Grid.ColumnDefinitions> 

        <AdornerDecorator Grid.Column="0"> 
         <ItemsControl Grid.Column="0" 
              HorizontalAlignment="Stretch" 
              VerticalAlignment="Stretch" 
              IsTabStop="False" 
              ItemsSource="{Binding Controls, 
                   Mode=OneWay}"> 
          <ItemsControl.ItemsPanel> 
           <ItemsPanelTemplate> 
            <WrapPanel Grid.Column="0" 
                Margin="10,5,0,0" 
                HorizontalAlignment="Stretch" 
                VerticalAlignment="Stretch" 
                Orientation="Vertical" /> 
           </ItemsPanelTemplate> 
          </ItemsControl.ItemsPanel> 
         </ItemsControl> 
        </AdornerDecorator> 
        </Grid> 
       </DataTemplate> 
      </TabControl.ContentTemplate> 
     </TabControl> 
    </Grid> 
</Window> 

主窗口代碼隱藏

public partial class MainWindow : Window 
{ 
    private DataContextObject obj = new DataContextObject(); 
    public MainWindow() 
    { 
     InitializeComponent(); 

     myTextBoxDef txt1 = new myTextBoxDef(obj, "Textbox 1", "TAB1TextBox1"); 
     myTextBoxDef txt1b = new myTextBoxDef(obj, "Textbox 1 value", "TAB1TextBox1"); 

     myTextBoxDef txt2 = new myTextBoxDef(obj, "Textbox 2", "TAB1TextBox2"); 
     myTextBoxDef txt2b = new myTextBoxDef(obj, "Textbox 2 value", "TAB1TextBox2"); 

     obj.Tabs.Add(new myTabDef("Tab 1", new ObservableCollection<myTextBoxDef>() { txt1, txt2 })); 
     obj.Tabs.Add(new myTabDef("Tab 2", new ObservableCollection<myTextBoxDef>() { txt1b, txt2b })); 

     obj.SelectedTab = obj.Tabs[0]; 

     this.DataContext = obj; 
    } 
} 

支持ing objects

public class DataContextObject : NotificationObject 
{ 
    List<myTabDef> _tabs = new List<myTabDef>(); 
    public List<myTabDef> Tabs 
    { 
     get 
     { 
      return _tabs; 
     } 
    } 

    private myTabDef _item; 
    public myTabDef SelectedTab 
    { 
     get 
     { return _item; } 
     set 
     { 
      _item = value; 
      this.RaisePropertyChanged("SelectedItem"); 
     } 
    } 

    private string _txt1 = ""; 
    public string TAB1TextBox1 
    { 
     get { return _txt1; } 
     set 
     { 
      _txt1 = value; 
      this.RaisePropertyChanged("TAB1TextBox1"); 
     } 
    } 

    private string _txt2 = ""; 
    public string TAB1TextBox2 
    { 
     get { return _txt2; } 
     set 
     { 
      _txt2 = value; 
      this.RaisePropertyChanged("TAB1TextBox2"); 
     } 
    } 

    private string _txt3 = ""; 
    public string TAB2TextBox1 
    { 
     get { return _txt3; } 
     set 
     { 
      _txt3 = value; 
      this.RaisePropertyChanged("TAB2TextBox1"); 
     } 
    } 
} 

public class myTabDef 
{ 
    public myTabDef(string tabText, ObservableCollection<myTextBoxDef> controls) 
    { 
     HeaderText = tabText; 
     _left = controls; 
    } 

    public string HeaderText { get; set; } 

    private ObservableCollection<myTextBoxDef> _left = new ObservableCollection<myTextBoxDef>(); 
    public ObservableCollection<myTextBoxDef> Controls 
    { 
     get 
     { 
      return _left; 
     } 
    } 
} 

public class myTextBoxDef : NotificationObject 
{ 
    public myTextBoxDef(NotificationObject bound, string label, string bindingPath) 
    { 
     LabelText = label; 
     Path = bindingPath; 
     BoundObject = bound; 

     BoundObject.PropertyChanged += BoundObject_PropertyChanged; 
    } 

    public string LabelText 
    { 
     get; 
     set; 
    } 

    public NotificationObject BoundObject 
    { 
     get; 
     set; 
    } 

    public string DocValue 
    { 
     get 
     { 
      return PropInfo.GetValue(BoundObject, null) as string; 
     } 
     set 
     { 
      PropInfo.SetValue(BoundObject, value, null); 
     } 
    } 

    protected virtual void BoundObject_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) 
    { 
     if (e.PropertyName.Equals(Path)) 
     { 
      this.RaisePropertyChanged("DocValue"); 
     } 
    } 

    public string Path 
    { 
     get; 
     set; 
    } 

    private PropertyInfo pi = null; 
    protected PropertyInfo PropInfo 
    { 
     get 
     { 
      if (pi == null && BoundObject != null && !string.IsNullOrEmpty(Path)) 
      { 
       PropertyInfo[] properties = BoundObject.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance); 

       pi = properties.Where((prop) => string.Compare(prop.Name, Path, true) == 0).FirstOrDefault(); 
      } 

      return pi; 
     } 
    } 
} 
+0

郵政代碼另一個鏈接。 XAML的綁定和獲取和設置 – Paparazzi 2013-04-05 18:39:26

+0

工作在一個簡化的版本。我會盡快對原始帖子進行修改。 – adondero 2013-04-05 20:17:09

+0

如果您使用添加的代碼創建項目,則應該在選項卡1上看到兩個文本框(並且其值也顯示在Tab2上)。如果您將一個值放入第一個文本框和第二個選項卡並輸入一個值。在刪除第二個文本框之前,單擊該選項卡。標籤2將更新爲Textbox 1值,但不包含文本框2. – adondero 2013-04-05 21:40:21

回答