2013-06-20 13 views
0

我有兩個自定義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;

我怎麼能AVO確定它,因爲我需要返回這兩種類型之一?

+1

爲什麼不擺脫所有這些東西,並使用兩個不同的'MouseDown'處理程序,一個用於UserControl01,另一個用於UserControl02? – Clemens

+0

問題是'UserControlX'不是'T'。其實你不需要'UserControlX',但是有一個'ViewModel'和'IsSelected'屬性。你爲什麼不定義合適的接口? –

+0

@Nico:thnx爲你的想法 – Sasha

回答

0

將您方法GetUserControlType的正文變爲類型檢查時出現問題。暫且擱置一會兒,想象一下我們的實現是GetUserControlType。它所做的是將其參數轉換爲您的類型之一。

返回類型爲T,一樣的參數類型,所以你的行

var tempUc = GetUserControlType(userControl); 

可以改寫爲

UserControl tempUc = GetUserControlType(userControl); 

userControl類型是UserControl。所以基本上,即使你可以弄明白,該方法只會返回其參數不變,並且具有相同的類型。你也應該認爲你在這一行中的含義是var--它會有一個特定的類型,它不能同時輸入UserControl01UserControl02

至於方法本身,線條

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; 

而且你的問題至於「是否可以用泛型來完成」,你應該將泛型看作是當類型無關緊要時可以使用的東西(當函數可以被寫爲時一般地而沒有某種類型的特殊情況分析可能的類型)。

+0

謝謝你的幫助 – Sasha

0

如果你真的需要有相同的MouseDown處理兩個用戶控件,你可以寫這樣的:

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

問題是我動態地創建userControl。所以我不知道會有多少userControls。使用泛型是不可能的? – Sasha

+0

這是可能的,但沒有必要。正如Nico所說,你可以使用一個返回ViewModel的公共接口。事件更簡單,爲什麼不只是通過UserControl的'DataContext'屬性訪問視圖模型實例。 – Clemens

+0

謝謝你的幫助。我會用像Nico這樣的界面來做 – Sasha

相關問題