0

我有两个自定义用户控件。当我想为 customUserControl 设置一些属性时,我必须这样做:

 private void OnRightMouseDown(object sender, MouseButtonEventArgs e)
 {
     var userControl = sender as UserControl;
     if (userControl != null)
         switch (userControl.Name)
         {
             case "UserControl01":
                 var uc01 = sender as UserControl01;
                 if (uc01 != null)
                 {
                     uc01.ViewModel.IsSelected = true;
                 }
                 break;
             case "UserControl02":
                 var uc02 = sender as UserControl02;
                 if (uc02 != null)
                 {
                     uc02.ViewModel.IsSelected = true;
                 }
                 break;                                                 
          }
     e.Handled = true;
 }

我想这样做:

private void OnRightMouseDown(object sender, MouseButtonEventArgs e)
 {
     var userControl = sender as UserControl;
     if (userControl != null)
        {
             var tempUc = GetUserControlType(userControl);
             tempUc.ViewModel.IsSelected = true;
        }
     e.Handled = true;
 }

为此,我制作了GetUserControlType方法:

private static T GetUserControlType<T>(T userControl)
    {
        if (userControl != null)
        {
            var uc = userControl as UserControl;
            switch (uc.Name)
            {
                case "UserControl01":
                    var tempUc1 = userControl as UserControl01;
                    return tempUc1;
                case "UserControl02":
                    var tempUc2 = userControl as UserControl02;
                    return tempUc2;
            }
        }
        return default(T);     
}

我得到错误 -Cannot convert expression type '' to return type 'T' in line return tempUc1;

我怎样才能避免它,因为我需要返回这两种类型中的一种?

4

2 回答 2

0

如果您确实需要MouseDown为两个 UserControls 使用相同的处理程序,您可以这样编写:

private void OnRightMouseDown(object sender, MouseButtonEventArgs e)
{
    var uc01 = sender as UserControl01;
    if (uc01 != null)
    {
        uc01.ViewModel.IsSelected = true;
        return;
    }

    var uc02 = sender as UserControl02;
    if (uc02 != null)
    {
        uc02.ViewModel.IsSelected = true;
    }
}

无论如何,更好的解决方案是有两个处理程序:

private void UserControl01_RightMouseDown(object sender, MouseButtonEventArgs e)
{
    ((UserControl01)sender).ViewModel.IsSelected = true;
}

private void UserControl02_RightMouseDown(object sender, MouseButtonEventArgs e)
{
    ((UserControl02)sender).ViewModel.IsSelected = true;
}
于 2013-06-20T11:35:10.803 回答
0

您在获取方法主体以进行类型检查时遇到问题GetUserControlType。暂且不说,想象一下我们有一个GetUserControlType. 这样做是将其参数转换为您的一种类型。

返回类型是T,与参数类型相同,所以你的行

var tempUc = GetUserControlType(userControl);

可以改写为

UserControl tempUc = GetUserControlType(userControl);

因为类型userControlUserControl. 因此,基本上,即使您可以对其进行类型检查,该方法也只会返回其参数不变,并且具有相同的类型。您还应该考虑您var在该行中的意思-它将具有一种特定类型,它不能同时具有 typeUserControl01UserControl02.

至于方法本身,行

var tempUc1 = userControl as UserControl01;
return tempUc1;

不要类型检查,因为返回类型T不是静态 UserControl01的。它们是否会在 if 语句的特定分支中处于运行时并不重要,它们必须在编译时具有正确的类型。

如评论中所述,您可以使用界面,例如:

interface IControlWithViewModel { public ISelectableViewModel { get; } }
interface ISelectableViewModel { public bool IsSelected { get; set; }

并让用户控件都实现这个接口 - 然后你写

var tempUc = (IControlWithViewModel)userControl;
tempUc.ViewModel.IsSelected = true;

关于“可以用泛型完成”的问题,您应该将泛型视为可以在类型无关紧要时使用的东西(当函数可以在没有某种特殊情况分析的情况下通用编写时)可能的类型)。

于 2013-06-20T12:04:44.667 回答