我有一个ItemsControl,ItemsSource绑定到IEnumerable< MyDataItem>。
ItemTemplate包含两个文本框。 (友好的名字和名字)。这就是它的样子:http://i.stack.imgur.com/Rg1dC.png
填写“友好名称”字段后,我会添加一个空行。我使用LostKeyboardFocus事件来检查是否添加一个空的“MyDataItem”并刷新IEnumerable< MyDataItem>属性。
问题:添加项目时我失去了焦点。因此,如果我从友好名称到名称并且添加了新行,则焦点将从名称中丢失。我该如何解决这个问题?
编辑:在某些代码下面显示我的问题。我想能够从一个细胞到另一个细胞进行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();
}
}
}
ViewModel
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 :(得分:0)
根据您的需要,ItemsControl并不友好,因为没有属性可以获得特定的选定项目。尝试使用Listbox相反,因为它公开了SelectedItem,SelectedIndex等属性,使用这些属性可以获得任何索引值的子控件。
PS:如果您希望使用alistbox并获取子元素,我可以详细说明我的答案。