【问题标题】:Using Generics on Classes with Static DependencyProperty在具有静态 DependencyProperty 的类上使用泛型
【发布时间】:2017-09-12 14:44:31
【问题描述】:

我们正在考虑为 DevExpress WPF 应用程序单视图模型上的验证创建一个辅助类。

在我们的 xaml 中,我们想要添加对 ValidationServiceHelper 类的引用:

<dxlc:DataLayoutControl x:Name="layoutControlMyObject" Style="{StaticResource EntityView.DataLayoutControl}"
    viewmodel:ValidationServiceHelper.HasErrors="{Binding RelativeSource={RelativeSource Self}, Path=(dxe:ValidationService.HasValidationError)}">

ValidationServiceHelper 类如下所示:

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);
            }
        }
    }
}

查看 OnHasErrorsChanged 中的两个 Dispatcher.BeginInvoke 调用,您会看到我将强制转换硬编码为 MyObjectViewModel。

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

这样写,我需要创建一个不同的辅助类。有没有办法让这个通用,所以我只能为我的所有视图模型使用一个类?

【问题讨论】:

    标签: c# wpf dependency-properties devexpress-wpf


    【解决方案1】:

    您可以从定义了ViewErrors 属性的公共基类(或实现接口)派生您的视图模型类,并将其转换为这种类型:

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

    但是您将永远无法将DataContext 转换为内存中对象的实际类型以外的任何其他类型。以一种或另一种方式使用泛型不会改变这一事实。

    并且没有办法将SingleObjectViewModel&lt;A, int, IMyEntityUnitOfWork&gt; 转换为SingleObjectViewModel&lt;B, int, IMyEntityUnitOfWork&gt;,因为这是两种完全不同的类型。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-21
    • 2012-05-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多