0

2 つのカスタム userControls があります。そして、いくつかのプロパティを 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;

この2つのタイプのいずれかを返す必要があるため、どうすれば回避できますか?

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

とにかく、より良い解決策は、2 つのハンドラーを持つことです。

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。これが行うことは、その引数キャストをあなたの型の 1 つに返すことです。

戻り値の型はT、引数の型と同じなので、あなたの行

var tempUc = GetUserControlType(userControl);

として書き換えることができます

UserControl tempUc = GetUserControlType(userControl);

の型はuserControlですUserControl。したがって、基本的に、型チェックを行うことができたとしても、メソッドは引数を変更せずに同じ型を返すだけです。また、その行で何を意味するかを考える必要がありますvar-それは特定の型を 1 つ持ち、 typeUserControl01との両方を持つことはできませんUserControl02

メソッド自体に関しては、行

var tempUc1 = userControl as UserControl01;
return tempUc1;

戻り値の型がstaticallyTではないため、型チェックを行わないでください。それらが実行時に if ステートメントの特定のブランチにあるかどうかは関係ありません。コンパイル時に正しい型を持っている必要があります。 UserControl01

コメントに記載されているように、次のようなインターフェイスを使用できます。

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 に答える