2017-09-12 8 views
-1

DevExpress WPF 응용 프로그램 단일보기 모델에서 유효성 검사를위한 도우미 클래스를 만들려고합니다. 우리의 XAML에서 Static DependencyProperty 클래스에서 Generics 사용

, 우리는 우리의 ValidationServiceHelper 클래스에 대한 참조를 추가 할 :

ValidationServiceHelper 클래스는 다음과 같습니다
<dxlc:DataLayoutControl x:Name="layoutControlMyObject" Style="{StaticResource EntityView.DataLayoutControl}" 
    viewmodel:ValidationServiceHelper.HasErrors="{Binding RelativeSource={RelativeSource Self}, Path=(dxe:ValidationService.HasValidationError)}"> 

:

namespace MyApplication.ViewModels 
{ 
    public partial class MyObjectViewModel : 
     SingleObjectViewModel<MyObject, int, IMyEntityUnitOfWork> 
    { 
     // ... 
    } 

    public class ValidationServiceHelper 
    { 
     public static bool GetHasErrors(DependencyObject obj) 
     { 
      return (bool)obj.GetValue(HasErrorsProperty); 
     } 

     public static void SetHasErrors(DependencyObject obj, bool value) 
     { 
      obj.SetValue(HasErrorsProperty, value); 
     } 

     public static readonly DependencyProperty HasErrorsProperty = 
      DependencyProperty.RegisterAttached("HasErrors", typeof(bool), 
      typeof(ValidationServiceHelper), new PropertyMetadata(false, OnHasErrorsChanged)); 

     private static void OnHasErrorsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
     { 
      try 
      { 
       FrameworkElement element = (FrameworkElement)d; 
       element.Dispatcher.BeginInvoke(new Action(() => 
        ((MyObjectViewModel)element.DataContext).ViewHasErrors = (bool)e.NewValue)); 
       var err = ValidationService.GetValidationErrors(d); 
       if (err != null) 
        element.Dispatcher.BeginInvoke(new Action(() => 
         ((MyObjectViewModel)element.DataContext).ViewErrors = 
        err.Select(p => p.ErrorContent).Distinct().Aggregate(
        (j, i) => string.Format("{0}{1}{2}", i, Environment.NewLine, j)).ToString())); 
      } 
      catch (Exception ex) 
      { 
       throw new Exception(ex.Message); 
      } 
     } 
    } 
} 

이 Dispatcher.BeginInvoke이 OnHasErrorsChanged에서 호출이 보면 MyObjectViewModel에 캐스트를 하드 코딩 한 것을 볼 수 있습니다.

element.Dispatcher.BeginInvoke(new Action(() => 
    ((MyObjectViewModel)element.DataContext).ViewHasErrors = (bool)e.NewValue)); 

이렇게 작성하면 다른 도우미 클래스를 만들어야합니다. 이 제네릭을 만드는 방법이 있나요? 그래서 모든 내보기 모델에 대해 하나의 클래스 만 사용할 수 있습니까?

답변

0

당신은 일반적인 기본 클래스에서 뷰 모델 클래스를 파생 (또는 인터페이스 구현)를 ViewErrors 속성이 이러한 유형의 정의 및 캐스팅 수 :

var vm = element.DataContext as BaseViewModel; 
if (vm != null) 
    element.Dispatcher.BeginInvoke(new Action(() => vm.ViewHasErrors = (bool)e.NewValue)); 

을하지만 당신은 캐스팅 할 수 없을 것 DataContext은 메모리에있는 객체의 실제 유형이 아닌 다른 유형으로 변환됩니다. 제네릭을 사용하는 것은이 사실을 바꾸지 않습니다.

두 가지 전혀 다른 유형이기 때문에 SingleObjectViewModel<A, int, IMyEntityUnitOfWork>SingleObjectViewModel<B, int, IMyEntityUnitOfWork>으로 전송할 방법이 없습니다.

+0

저는 ViewErrors가 기본 클래스 인 SingleObjectViewModel의 일부라고 믿습니다. 그러나이 클래스는 사용하는 EF 모델을 나타 내기 위해 세 가지 유형의 인수가 필요합니다. – Pizzor2000

+0

속성을 일반 클래스의 비 제네릭 기본 클래스로 이동하거나 인터페이스를 구현하고이 클래스로 캐스트합니다. – mm8

+0

앞서 말했듯이이 두 가지 완전히 다른 유형이기 때문에 SingleObjectViewModel 를 SingleObjectViewModel 로 캐스팅 할 수있는 방법은 없습니다. int에 Button을 캐스팅하는 것과 같으며 항상 실패합니다. 유형 매개 변수가 다른 제네릭 유형의 두 인스턴스는 두 가지 완전히 다른 유형입니다. 제네릭 정의 자체는 모든 제네릭 형식을위한 기본 클래스가 아닙니다. – mm8