因爲你可以從這裏開始驗證部分:http://codeblitz.wordpress.com/2009/05/08/wpf-validation-made-easy-with-idataerrorinfo/
後你理解文章,你可以修改你的類是這樣的: 例如,讓我們添加的職位和工作開始日期非空標題驗證:
作業類:
public class Job : IDataErrorInfo
{
public string Title { get; set; }
public DateTime? Start { get; set; }
public DateTime? End { get; set; }
public string Error
{
get { throw new NotImplementedException(); }
}
public string this[string columnName]
{
get
{
string result = null;
if (columnName == "Title")
{
if (string.IsNullOrEmpty(Title))
result = "Please enter a Title ";
}
if (columnName == "Start")
{
if (Start == null)
result = "Please enter a Start Date";
else if (Start > End)
{
result = "Start Date must be less than end date";
}
}
return result;
}
}
}
//////////假設我們使用了一種叫做主窗口窗口,供您XAML代碼它看起來像 MainWindow.xaml
個
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
x:Name="mainWindow">
<Window.Resources>
<ControlTemplate x:Key="errorTemplate">
<DockPanel LastChildFill="true">
<Border Background="Red" DockPanel.Dock="right" Margin="5,0,0,0" Width="20" Height="20" CornerRadius="10"
ToolTip="{Binding ElementName=customAdorner, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}">
<TextBlock Text="!" VerticalAlignment="center" HorizontalAlignment="center" FontWeight="Bold" Foreground="white">
</TextBlock>
</Border>
<AdornedElementPlaceholder Name="customAdorner" VerticalAlignment="Center" >
<Border BorderBrush="red" BorderThickness="1" />
</AdornedElementPlaceholder>
</DockPanel>
</ControlTemplate>
</Window.Resources>
<Grid>
<StackPanel Orientation="Horizontal">
<ListView ItemsSource="{Binding}" Width="200" DisplayMemberPath="Name" IsSynchronizedWithCurrentItem="True" IsEnabled="{Binding ElementName=mainWindow, Path=FormHasNoNoErrors}"/>
<DockPanel Width="200" Margin="10,0">
<TextBox Text="{Binding Name}" DockPanel.Dock="Top" Margin="0,0,0,10"/>
<ListView ItemsSource="{Binding Jobs}" Name="_jobList" DisplayMemberPath="Title" IsSynchronizedWithCurrentItem="True" IsEnabled="{Binding ElementName=mainWindow, Path=FormHasNoNoErrors}" />
</DockPanel>
<StackPanel Width="200" DataContext="{Binding ElementName=_jobList, Path=SelectedItem}">
<TextBox Text="{Binding Title, ValidatesOnDataErrors=true, NotifyOnValidationError=true}" Validation.Error="Validation_OnError" Validation.ErrorTemplate="{StaticResource errorTemplate}"/>
<DatePicker SelectedDate="{Binding Start, ValidatesOnDataErrors=true, NotifyOnValidationError=true}" Validation.Error="Validation_OnError" Validation.ErrorTemplate="{StaticResource errorTemplate}"/>
<DatePicker SelectedDate="{Binding End}"/>
</StackPanel>
</StackPanel>
</Grid>
</Window>
////////MainWindow.xaml.cs
public partial class MainWindow : Window, INotifyPropertyChanged
{
public MainWindow()
{
var jobs1 = new ObservableCollection<Job>()
{
new Job() {Start = DateTime.Now, End = DateTime.Now.AddDays(1), Title = "Physical Enginer"},
new Job() {Start = DateTime.Now, End = DateTime.Now.AddDays(1), Title = "Mechanic"}
};
var jobs2 = new ObservableCollection<Job>()
{
new Job() {Start = DateTime.Now, End = DateTime.Now.AddDays(1), Title = "Doctor"},
new Job() {Start = DateTime.Now, End = DateTime.Now.AddDays(1), Title = "Programmer"}
};
var personList = new ObservableCollection<Person>()
{
new Person() {Name = "john", Jobs = jobs1},
new Person() {Name="alan", Jobs=jobs2}
};
this.DataContext = personList;
InitializeComponent();
}
private void Validation_OnError(object sender, ValidationErrorEventArgs e)
{
if (e.Action == ValidationErrorEventAction.Added)
NoOfErrorsOnScreen++;
else
NoOfErrorsOnScreen--;
}
public bool FormHasNoNoErrors
{
get { return _formHasNoErrors; }
set
{
if (_formHasNoErrors != value)
{
_formHasNoErrors = value;
PropertyChanged(this, new PropertyChangedEventArgs("FormHasNoErrors"));
}
}
}
public int NoOfErrorsOnScreen
{
get { return _noOfErrorsOnScreen; }
set
{
_noOfErrorsOnScreen = value;
FormHasNoNoErrors = _noOfErrorsOnScreen == 0 ? true : false;
}
}
private int _noOfErrorsOnScreen = 0;
private bool _formHasNoErrors = true;
public event PropertyChangedEventHandler PropertyChanged = delegate {};
}
//////////////////////
我想驗證工作 場,使得用戶不能選擇 另一個工作(或個人)如果標題 爲空或 同一個人中的重複,或者如果日期是出 Ø f命令。此外,如果姓名爲 爲空,則不能更改人員 。
一個簡單的解決方案是,如果表單有錯誤(這是我在上面的代碼中做的),禁用列表框,並在沒有錯誤時啓用它們。另外你也許應該在工具提示上放一個漂亮的紅色邊框,解釋用戶爲什麼不能再選擇。
爲驗證標題是否在同一個人中重複,可以擴展上面的驗證機制以使ValidationService類接收一個Person並查看擁有該作業的人是否也具有另一個具有相同名稱的人。
公共類人:IDataErrorInfo的 {
public string this[string columnName]
{
get
{
//look inside person to see if it has two jobs with the same title
string result = ValidationService.GetPersonErrors(this);
return result;
}
...
}
而且,我結合確定我設置 的方式在DataContext像 的最後一個面板上?它的工作原理,但它略微感覺有點 。替代方案是爲 CollectionDataSources聲明 資源,並且我不能 實際上很容易將該方法排除在外 。
這不是在MVVM精神,如果你正在做什麼,將是東西比一個小的測試項目,你應該嘗試學習MVVM更多(你可以從這裏開始:http://fernandomachadopirizen.wordpress.com/2010/06/10/a-simple-introduction-to-the-model-view-viewmodel-pattern-for-building-silverlight-and-windows-presentation-foundation-applications/)然後
你不會直接綁定到人員列表,而是您將擁有一些您綁定的MainWindowViewModel類。這個MainWindowViewModel類將包含人員列表,您將綁定到該列表。 而對於選擇,你會在你的MainWindowViewModel一個CurrentJob特性,那就是當前選擇的工作,你會綁定到:
基本上是這樣的:
<StackPanel Orientation="Horizontal">
<ListView ItemsSource="{Binding PersonList}" SelectedItem="{Binding CurrentPerson, Mode=TwoWay}" Width="200" DisplayMemberPath="Name" IsSynchronizedWithCurrentItem="True" IsEnabled="{Binding ElementName=mainWindow, Path=FormHasNoNoErrors}"/>
<DockPanel Width="200" Margin="10,0">
<TextBox Text="{Binding Name}" DockPanel.Dock="Top" Margin="0,0,0,10"/>
<ListView ItemsSource="{Binding Jobs}" SelectedItem="{Binding CurrentJob, Mode=TwoWay}", DisplayMemberPath="Title" IsSynchronizedWithCurrentItem="True" />
</DockPanel>
<StackPanel Width="200">
<TextBox Text="{Binding CurrentJob.Title}"/>
.....
</StackPanel>
</StackPanel>
而且你MainWindowViewModel:
public class MainWindowViewModel :
{
...
//Public Properties
public ObservableCollection<Person> PersonList ....
public Job CurrentJob ....
....
}
我已經嘗試在我的數據類中實現IDataErrorInfo,並將ValidatesOnDataErrors = True放入我的綁定中。這正確地突出顯示錯誤的字段,但不會阻止導航。 – captncraig 2011-04-08 19:13:43