簡體   English   中英

WPF 帶有通用代碼隱藏的用戶控件

[英]WPF UserControl with generic code-behind

我背后有這段代碼:

CustomUserControl.xaml.cs

namespace MyProject
{
    public partial class CustomUserControl<T> : UserControl
    {
        ...
    }
}

和這個 xaml:

CustomUserControl.xaml

<UserControl x:Class="MyProject.CustomUserControl"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:sys="clr-namespace:System;assembly=mscorlib">
<Grid>

</Grid>

它不起作用,因為 x:Class="MyProject.CustomUserControl" 與代碼隱藏的通用 class 定義不匹配。 有什么方法可以使這項工作嗎?

您可以在沒有XAML文件的情況下創建通用的“代碼隱藏”文件:

public class CustomUserControl<T>: UserControl
{ }

而不是從它提供特定的類作為參數:

public partial class SpecificUserControl : CustomUserControl<Presenter>
{
    public SpecificUserControl()
    {
        InitializeComponent();
    }
}

XAML:

<application:CustomUserControl 
     x:TypeArguments="application:Presenter"
     xmlns:application="clr-namespace:YourApplicationNamespace"
...

不幸的是,在Visual Studio 2012 Update 2之前,Visual Studio設計器似乎不支持此類泛型(請參閱https://stackoverflow.com/a/15110115/355438

到目前為止,還沒有找到我的解決方案。 主要的區別是,我有一個.xaml文件用於通用用戶控件類,而不是每個實際用戶控件一個.xaml文件。

GenericUserControl.xaml.cs

using System.Windows.Controls;

namespace TestGenericUserControl
{
    public abstract partial class GenericUserControl : UserControl
    {
        // If you use event handlers in GenericUserControl.xaml, you have to define 
        // them here as abstract and implement them in the generic class below, e.g.:

        // abstract protected void MouseClick(object sender, MouseButtonEventArgs e);
    }

    public class GenericUserControl<T> : GenericUserControl
    {
        // generic properties and stuff

        public GenericUserControl()
        {
            InitializeComponent();
        }
    }

    // To use the GenericUserControl<T> in XAML, you could define:
    public class GenericUserControlString : GenericUserControl<string> { }
    // and use it in XAML, e.g.:
    // <GenericUserControlString />
    // alternatively you could probably (not sure) define a markup extension to instantiate
    // it directly in XAML
}

GenericUserControl.xaml

<UserControl x:Class="TestGenericUserControl.GenericUserControl"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
        mc:Ignorable="d">
    <Grid>
        <Label Content="hello" />
    </Grid>
</UserControl>

不幸的是,XAML不支持通用代碼,你可以繞過它。

請參閱以下鏈接:

http://forums.silverlight.net/forums/p/29051/197576.aspx

我可以在XAML(.NET 4 Framework之前版本)中指定泛型類型嗎?

可能是未來版本的Visual Studuo與XAML 2009本身支持通用控件。

我最終得到了一個額外的幫助程序 class,這不是 UserControl。 對於需要通用類型的簡單自定義 UserControl,它可以很好地完成工作。

所以 UserControl,例如 UCMoveObject,有一個 InitFunction 返回給我的 Helper 實例:

// In the UCMoveObjects UserControl Class.
public UCMoveObjectsHelper<T> InitUCMoveObject<T>(List<T> argAllList, List<T> argSelectedList)
{
     return new UCMoveObjectsHelper<T>(this, argAllList, argSelectedList);
}

然后在幫助程序 class 中,我放置了使用戶控件正常工作的所有代碼。

public class UCMoveObjectsHelper<T>
{

public UCMoveObjectsHelper(UCMoveObjects argUserControl, List<T> argAllList, List<T> argSelected)
{
   _ucMoveObjects = argUserControl;

   // Example reaching the usercontrol
   _ucMoveObjects.listBox.SelectionChanged += LbAll_SelectionChanged;

   // Do whatever I want with T
}

public List<T> ReturnSelected()
{
     // Code that return a List<T>;
}

}

在 MainWindow.xaml 中,我在 window 中放置了一個用戶控件。然后在代碼中執行以下操作:

  _ucMovingObjectsHelper = ucMovingObjects.InitUCMoveObject<TblUsers>(tempListAll, tempListSelected);

稍后在我的代碼中我可以調用:

var tempSelectedList = _ucMovingObjectsHelper.ReturnSelected();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM