3

まず、これが可能かどうか疑問に思います。私はこれについてインターネットの周りでわずかな不平を読んだが、私は完全に確信していなかった。

私のシナリオ:すべてのチャートに必要ないくつかのメソッドを持つ基本チャートクラスがあります。

public partial class BaseChart : System.Web.UI.UserControl
{
    public BaseChart()
    {
    }

    public void ToggleLegend()
    {
        Chart1.Legends[0].Enabled = !Chart1.Legends[0].Enabled;
    }
}

このBaseChartにはいくつかのマークアップもあります-背景色の設定など。BaseChartを継承するすべてのチャートは、この開始マークアップを使用し、それに基づいて構築できる必要があります。

次に、これを実行したいと思います。

public partial class HistoricalLineChart : BaseChart
{
    public HistoricalLineChart()
        : base()
    {
    }

    public HistoricalLineChart(int reportID)
        : base()
    {
        Chart1.Titles[0].Text = "Hello World";
    }
 }

ここで、HistoricalLineChartは、マークアップのないWebユーザーコントロールです(例:「HistoricalLineChart.ascx」)。

問題は、HistoricalLineChartのスコープ内にあるときにChart1が定義されていないことです。ここで欠けているものはありますか?

ありがとう。

4

3 に答える 3

2

通常、この状況ではカスタムコントロールを作成するだけで済みますが(他の回答が示唆しているように)、これは多くの理由で有効ですが、複雑なマークアップによってサーバーコントロールが実行不可能になる状況で役立つ可能性のある他のアプローチがいくつかあります。

1)実装に共通のすべての機能を持ち、UserControlを継承する基本クラスを作成します。マークアップを基本クラスの一部として本当に含めたい場合は、コードなしで別のユーザーコントロールに配置し、抽象クラスからロードすることができますが、これは少し醜いようです。ただし、共有されるマークアップが単純な場合は、代わりにコードからレンダリングするだけです。

public abstract class MyUserControl: UserControl
{
     public Chart Chart1;
     public void ToggleLegend()
    {
        Chart1.Legends[0].Enabled = !Chart1.Legends[0].Enabled;
    }
    public override void CreateChildControls()
    {
        Controls.Add(Page.LoadControl("path/to/mymarkup/control"));
        // or add them in code
        BuildBaseControls();
    }
}

2)UserControlの代わりにMyUserControlを継承するUserControl実装を作成し、マークアップを追加します

public partial class HistoricalLineChart : MyUserControl
{
    public HistoricalLineChart(int reportID)
        : base()
    {
        Chart1.Titles[0].Text = "Hello World";
    }
}

マークアップに表示する必要のあるコントロールを説明するインターフェイスを作成し、それを実装することもできます。これは、UserControl(コントロールがマークアップで定義されている)またはWebControl(コントロールがコードで作成されている)のいずれかに適用できる構造を提供し、マークアップの実際の詳細を各実装に任せるので便利ですが、機能を共有できます。

于 2011-02-28T22:59:53.920 に答える
1

残念ながら、のマークアップ部分BaseChartは実際にはBaseChartクラスの一部ではありません。マークアップは、コンパイル時に作成されるクラスの一部であり、から継承しBaseChartます。したがってHistoricalLineChart、明示的に設定したもののみが含まれBaseChart、マークアップは含まれません。これを回避するために私が知っている唯一の方法は、コンポジットコントロールまたはカスタムサーバーコントロール(ユーザーコントロールではなく)を使用することです。プログラムで子コントロールを追加する必要があるため、少し面倒ですが、必要に応じて実行する必要があります。

次に例を示します。http://msdn.microsoft.com/en-us/library/3257x3ea (v = VS.100).aspx

基本的に:

  1. から継承しCompositeControlます。
  2. オーバーライドしCreateChildControlsます。この方法では、すべての子コントロール(グラフなど)を追加できます。
  3. オプション:オーバーライドRender。子コントロールに加えてカスタムマークアップが必要な場合は、これをオーバーライドします。カスタムマークアップを出力し、すべての子コントロールを呼び出しRenderControlて、出力をレンダリングする場所を指示できます。このメソッドをまったくオーバーライドしない場合、複合コントロールは、コントロールコレクションにある順序で子コントロールをレンダリングします。

さらにいくつかのチュートリアルがあります:

于 2011-02-28T21:52:58.473 に答える
0

チャートを公開するprotectedプロパティを作成できます。BaseChart

于 2011-02-28T21:52:09.740 に答える