젠장, 생각만큼 시간이 좀 걸렸지 만 언제나처럼 ... 구조에 대한 행동을 취했습니다.
본질적으로보고있는 것은 더티 상태 추적입니다. ViewModel을 사용하여이 작업을 수행하는 방법은 여러 가지가 있지만 엔티티를 변경하지 않으려는 경우 가장 좋은 방법은 비헤이비어를 사용하는 것입니다.
우선 Xaml 바인딩에서 ValidatesOnDataErrors를 제거하십시오. 작업중인 컨트롤 (아래) 및 TextChanged
(또는 원하는 이벤트)의 동작을 이 아닌이 데이터 오류에 대해 유효성 검사를 수행하는 것으로 재설정합니다. 정말 간단합니다.
이 방법을 사용하면 엔티티를 변경할 필요가 없으며 Xaml은 합리적으로 깨끗하게 유지되고 사용자가 동작합니다.
여기
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
namespace IDataErrorInfoSample
{
public static class DirtyStateBehaviours
{
public static string GetDirtyBindingProperty(DependencyObject obj)
{
return (string)obj.GetValue(DirtyBindingPropertyProperty);
}
public static void SetDirtyBindingProperty(DependencyObject obj, string value)
{
obj.SetValue(DirtyBindingPropertyProperty, value);
}
// Using a DependencyProperty as the backing store for DirtyBindingProperty. This enables animation, styling, binding, etc...
public static readonly DependencyProperty DirtyBindingPropertyProperty =
DependencyProperty.RegisterAttached("DirtyBindingProperty", typeof(string), typeof(DirtyStateBehaviours),
new PropertyMetadata(new PropertyChangedCallback(Callback)));
public static void Callback(DependencyObject obj,
DependencyPropertyChangedEventArgs args)
{
var textbox = obj as TextBox;
textbox.TextChanged += (o, s) =>
{
Binding b = new Binding(GetDirtyBindingProperty(textbox));
b.ValidatesOnDataErrors = true;
textbox.SetBinding(TextBox.TextProperty, b);
};
}
}
}
코드 - 행동의 그리고 XAML은 꽤 똑바로 앞으로이다.
<Window x:Class="IDataErrorInfoSample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:IDataErrorInfoSample"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="MainWindow"
Height="350"
Width="525">
<Window.DataContext>
<local:Person />
</Window.DataContext>
<StackPanel Margin="20">
<TextBox Height="20"
Margin="0,0,0,10"
local:DirtyStateBehaviours.DirtyBindingProperty="Name"
Text="{Binding Path=Name}">
</TextBox>
<Button Content="Go" />
</StackPanel>
HTH, Stimul8d.
저는 해킹이없는 해결책을 원할 경우이 질문에 현상금을드립니다. –
InitializeComponent()가 호출되기 전에 Person을 생성 할 수 없습니까? – markmnl
좋은 해킹없는 솔루션을 얻으려면 bounty를 추가했습니다. –