2014-01-21 6 views
0

ItemsSource가 IEnumerable < MyDataItem>에 바인딩 된 ItemsControl이 있습니다.DataTemplate textbox가 Itemscontrol에 항목이 추가 될 때 포커스를 잃지 않도록하는 방법?

ItemTemplate은 두 개의 텍스트 상자로 구성됩니다. (친숙한 이름 & 이름). 이것은 다음과 같습니다. http://i.stack.imgur.com/Rg1dC.png

"Friendly name"필드가 채워지 자마자 빈 행을 추가합니다. LostKeyboardFocus 이벤트를 사용하여 빈 "MyDataItem"을 추가하고 IEnumerable < MyDataItem> 속성을 ​​새로 고칠 지 여부를 확인합니다.

문제 : 항목을 추가 할 때 초점이 느슨합니다. 그래서 친숙한 이름에서 이름으로 탭하고 새 행을 추가하면 이름에서 포커스가 사라집니다. 이 문제를 어떻게 해결할 수 있습니까?

EDIT : 내 문제를 나타내는 코드 아래에. 셀에서 셀로 탭 할 수 있어야합니다. 행의 두 셀이 모두 비어 있으면 해당 행을 제거하려고합니다. 마지막에는 빈 행 (양쪽 셀이 비어 있음)을 갖고 싶습니다. 이 시점에서 코드는 작동하지만 탭을 사용하면 포커스가 사라집니다. 목록 상자로 작업하면 해당 탭이 목록의 다음 항목으로 이동하지 않습니다.

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은 perticular 선택한 항목을 얻을 수있는 속성이 없으므로 필요에 따라 그다지 친절하지 않습니다. ListItem 대신 SelectedItem, SelectedIndex 등의 속성을 표시하므로 목록 상자를 사용해보십시오. 이러한 속성을 사용하면 모든 인덱스 값에서 하위 컨트롤을 가져올 수 있습니다.

추신 : 당신이 alistbox를 사용하고 자식 요소를 얻으 려한다면 내 대답을 자세히 설명 할 수 있습니다.

+0

답장을 보내 주셔서 감사합니다. 그러나 목록 상자를 사용하면 포커스를 잃는 데 어떻게 도움이되는지 알 수 없습니다. – jim