2014-01-21 54 views
0

我有一个ItemsControl绑定到IEnumerable < MyDataItem>的ItemsControl。如何防止DataTemplate文本框在项目添加到ItemsControl时失去焦点?

ItemTemplate包含两个文本框。 (友好名称&名称)。这是它的样子:http://i.stack.imgur.com/Rg1dC.png

只要填入“友好名称”字段,我将添加一个空行。我使用LostKeyboardFocus事件来检查是否添加一个空的“MyDataItem”并刷新IEnumerable属性MyDataItem。

问题:添加项目时我放松了焦点。因此,如果我从友好名称中选择名称并添加新行,焦点将从名称中丢失。我该如何解决这个问题?

编辑:在一些代码下面显示我的问题。我希望能够从单元格到单元格的TAB。当一行的两个单元格留空时,我想删除该行。最后我想有一个空行(两个单元格都是空的)。此时代码可以正常工作,但如果您使用Tab,则会失去焦点。并且使用列表框使TAB无法转到列表中的下一个项目。

XAML:

<Window x:Class="Focus.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:Focus" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    mc:Ignorable="d" 
    d:DataContext="{d:DesignInstance Type=local:MainViewModel, IsDesignTimeCreatable=True}" 
    Title="MainWindow" Height="350" Width="525"> 
<Window.Resources> 
    <DataTemplate x:Key="DataTemplate1"> 
     <Grid> 
      <Grid.ColumnDefinitions> 
       <ColumnDefinition /> 
       <ColumnDefinition Width="5"/> 
       <ColumnDefinition /> 
      </Grid.ColumnDefinitions> 
      <TextBox LostKeyboardFocus="TextBox_LostKeyboardFocus"> 
       <TextBox.Text> 
        <Binding Path="FriendlyName" UpdateSourceTrigger="PropertyChanged"/> 
       </TextBox.Text> 
      </TextBox> 
      <TextBox Grid.Column="2" LostKeyboardFocus="TextBox_LostKeyboardFocus"> 
       <TextBox.Text> 
        <Binding Path="Name" UpdateSourceTrigger="PropertyChanged"/> 
       </TextBox.Text> 
      </TextBox> 
     </Grid> 
    </DataTemplate> 

</Window.Resources> 
<Grid> 
    <ListBox Margin="10" ItemsSource="{Binding OrderedItems}" ItemTemplate="{DynamicResource DataTemplate1}" HorizontalContentAlignment="Stretch"> 

    </ListBox> 
</Grid> 

后面的代码:

using System.Windows; 
using System.Windows.Input; 

namespace Focus 
{ 
    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 
      this.DataContext = new MainViewModel(); 
     } 

     private void TextBox_LostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e) 
     { 
      MainViewModel vm = this.DataContext as MainViewModel; 
      vm.CheckToAddEmptyItem(); 
     }   
    } 
} 

视图模型

using System.Collections.Generic; 
using System.ComponentModel; 
using System.Linq; 

namespace Focus 
{ 
    public class MainViewModel : INotifyPropertyChanged 
    { 
     private List<MyItem> _myItems = new List<MyItem>(); 
     public IEnumerable<MyItem> OrderedItems 
     { 
      get { return _myItems.OrderBy(i => i.IsEmpty); } 
     } 

     internal void CheckToAddEmptyItem() 
     { 
      int count = _myItems.Count(i => i.IsEmpty); 

      if (count == 0) 
      { 
       _myItems.Add(new MyItem()); 

       if (null != PropertyChanged) 
        PropertyChanged(this, new PropertyChangedEventArgs("OrderedItems")); 
      } 
      else if (count > 1) 
      { 
       var items = _myItems.Where(i => i.IsEmpty).Skip(1).ToArray(); 

       foreach (MyItem item in items) 
        _myItems.Remove(item); 

       if (null != PropertyChanged) 
        PropertyChanged(this, new PropertyChangedEventArgs("OrderedItems")); 
      } 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 

     public MainViewModel() 
     { 
      for(int i=1; i <= 5; ++i) 
      { 
       _myItems.Add(new MyItem() { FriendlyName = "Item #" + i, Name = "ITEM" + i }); 
      } 

      if (null != PropertyChanged) 
       PropertyChanged(this, new PropertyChangedEventArgs("OrderedItems")); 

      CheckToAddEmptyItem(); 
     } 
    } 
} 

的MyItem类:

using System.ComponentModel; 

namespace Focus 
{ 
    public class MyItem : INotifyPropertyChanged 
    { 
     public event PropertyChangedEventHandler PropertyChanged; 

     private string _name = string.Empty;  
     public string Name 
     { 
      get { return _name; } 
      set 
      { 
       if (value != _name) 
       { 
        _name = value; 
        if (null != PropertyChanged) 
        { 
         PropertyChanged(this, new PropertyChangedEventArgs("Name")); 
         PropertyChanged(this, new PropertyChangedEventArgs("IsEmpty")); 
        } 
       } 
      } 
     } 

     private string _friendlyName = string.Empty; 
     public string FriendlyName 
     { 
      get { return _friendlyName; } 
      set 
      { 
       if (value != _friendlyName) 
       { 
        _friendlyName = value; 
        if (null != PropertyChanged) 
        { 
         PropertyChanged(this, new PropertyChangedEventArgs("FriendlyName")); 
         PropertyChanged(this, new PropertyChangedEventArgs("IsEmpty")); 
        } 
       } 
      } 
     } 

     public bool IsEmpty 
     { 
      get { return string.IsNullOrEmpty(Name) && string.IsNullOrEmpty(FriendlyName); } 
     } 
    } 
} 
+0

您需要在添加新元素并将其聚焦后,在ItemTemplate中找到TextBox。看看这个答案在模板中找到你的控件:[在ItemTenplate中查找控件](http://stackoverflow.com/questions/21234459/collapse-opened-expanders-in-datatemplate-when-we-open-new-one/21236051 #21236051) –

+0

我会研究它。谢谢回复。 – jim

回答

0

根据您的需求,ItemsControl并不那么友好,因为没有属性可以获得特定的选定项目。尝试使用列表框相反,因为它暴露像SelectedItem,SelectedIndex等属性,使用这些属性,您可以获得任何索引值的子控件。 PS:如果你想使用alistbox并获取子元素,我可以详细说明我的答案。

+0

感谢您的回复,但我不明白如何使用列表框将帮助我失去焦点。 – jim

相关问题