2014-01-21 55 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

相關問題