【发布时间】:2011-12-30 04:56:02
【问题描述】:
我有一个由 TabControl 组成的 WPF 应用程序。为了这个问题,我制作了一个简单的版本:
在第一个选项卡中,我有填充数据网格的组合框。如果我在数据网格中选择了一行,它将绑定几个文本框,用户可以编辑其内容。
我在数据网格中的对象实现了 IDataErrorInfo 接口,并且我的文本框在 {binding} 中设置了 ValidatesOnDataErrors=True。因此,如果我删除 Name 文本框的内容,它会变得无效(在文本框失去焦点之后):
现在,如果它无效,我不希望用户能够在数据网格中选择另一行,或在组合框中选择另一行(这将重新填充数据网格)。基本上我希望用户在他/她继续之前更正名称。不过,如果用户可以切换标签,我会更喜欢。
因此,如果绑定的对象无效,我要么需要禁用左侧的控件,要么如果单击左侧的控件,我需要将焦点设置到无效的文本框。我还没有找到任何合适的事件或绑定。感谢所有想法。
这是我的 XAML:
<Window x:Class="WpfValidationTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="350">
<TabControl>
<TabItem Header="Tab 1">
<StackPanel Orientation="Horizontal">
<StackPanel Orientation="Vertical">
<ComboBox>
<ComboBox.Items>
<ComboBoxItem Content="Friends"/>
<ComboBoxItem Content="Business"/>
</ComboBox.Items>
</ComboBox>
<DataGrid Name="dg" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding Name}" />
<DataGridTextColumn Header="Address" Binding="{Binding Address}" />
</DataGrid.Columns>
</DataGrid>
</StackPanel>
<StackPanel Orientation="Vertical" Width="200" Margin="10,0,0,0">
<TextBlock Text="Edit" FontWeight="Bold"/>
<TextBlock Text="Name:"/>
<TextBox Text="{Binding Path=SelectedItem.Name, ElementName=dg, ValidatesOnDataErrors=True}" />
<TextBlock Text="Address:"/>
<TextBox Text="{Binding Path=SelectedItem.Address, ElementName=dg, ValidatesOnDataErrors=True}" />
</StackPanel>
</StackPanel>
</TabItem>
<TabItem Header="Tab 2">
<TextBlock Text="The user should be able to navigate to this tab even if there are validation errors" TextWrapping="Wrap" />
</TabItem>
</TabControl>
</Window>
下面是代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;
namespace WpfValidationTest
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
List<Person> persons = new List<Person>()
{
new Person(){Name="John Doe", Address="My street 203"},
new Person(){Name="Jane Doe", Address="Your street 43"}
};
dg.ItemsSource = persons;
}
}
public class Person : INotifyPropertyChanged, IDataErrorInfo
{
public event PropertyChangedEventHandler PropertyChanged;
public string Error
{
get { throw new NotImplementedException(); }
}
public string this[string columnName]
{
get
{
switch (columnName)
{
case "Name":
if (string.IsNullOrEmpty(Name))
return "Name must be entered";
break;
case "Address":
if (string.IsNullOrEmpty(Address))
return "Address must be entered";
break;
}
return null;
}
}
private string _name;
public string Name
{
get { return _name; }
set
{
_name = value;
NotifyPropertyChanged("Name");
}
}
private string _address;
public string Address
{
get { return _address; }
set
{
_address = value;
NotifyPropertyChanged("Address");
}
}
private void NotifyPropertyChanged(string propName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
}
【问题讨论】:
-
感谢 Merlyn Morgan-Graham 添加图片。我是新会员,无法添加。
标签: wpf validation focus