2013-04-05 100 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

回答