web-dev-qa-db-ja.com

WPFのユーザーコントロールからの継承

私はWPFを初めて使用し、ユーザーコントロールからの継承に問題があります。

ユーザーコントロールを作成しましたが、そのコントロールから継承して、いくつかの機能を追加する必要があります。

誰かが以前にこのようなことをしたことがありますか?どんな助けでも大歓迎です。

ありがとうございました

30
user35129

私の知る限り、xamlを継承することはできません。背後にあるコードのみを継承できます。

最近、プロジェクトで同じ問題が発生しました。最終的に問題を解決する方法は、ユーザーコントロールを作成して「子」ユーザーコントロールに追加することでした。

それが機能しない場合/ヘルプはこれを見てください: http://geekswithblogs.net/lbugnion/archive/2007/03/02/107747.aspx1

15
BFreeman

さて..あなたはあなたのベースコントロールを作成します

public abstract class BaseUserControl : UserControl{...}

次に、XAMLファイルで:

<Controls:BaseUserControl x:Class="Termo.Win.Controls.ChildControl"
xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
xmlns:Controls="clr-namespace:Namespace.Of.Your.BaseControl">

そして、それはうまくいくはずです。

EDIT:うーん..この例は、XAMLなしの基本コントロールがあり、そこから継承する場合に役立ちます。逆の方法(Xamlを使用した基本コントロールから)-どうすればよいかわかりません。

EDIT2:どうやら この投稿+コメントから 私は、あなたが望むものは不可能かもしれないと思っています。

27
sirrocco

私は少し解決策を持っているかもしれません:継承ではなく構成-データバインディングを介して外部から割り当て可能な「コンテンツスロット」を持っているコントロールを思いついたので、私の SOスレッド を見てください。

使用例:

<UserControl ... >

    <!-- My wrapping XAML -->
        <Common:DialogControl>
                <Common:DialogControl.Heading>
                        <!-- Slot for a string -->
                </Common:DialogControl.Heading>
                <Common:DialogControl.Control>
                        <!-- Concrete dialog's content goes here -->
                </Common:DialogControl.Control>
                <Common:DialogControl.Buttons>
                        <!-- Concrete dialog's buttons go here -->
                </Common:DialogControl.Buttons>
        </Common:DialogControl>
    <!-- /My wrapping XAML -->

</UserControl>

分離コード内のいくつかの処理コードと共に、それはダイアログウィンドウの素敵な基本コンポーネントになります。

4
Tomáš Kafka

Xamlコードを自分で継承することはできません。ただし、分離コードの抽象クラスを作成すると、派生クラスオブジェクトからコードビハインドで編集できます。

Xamlコード:{Window1.xaml}

<Window 
x:Class="WPFSamples.Window1"
xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
Height="auto" Width="256" Title="WPF Sameples">
  <Grid>
    <Button x:Name="Button1" VerticalAlignment="Center" HorizontalAlignment="Center" Content="Click Me"/>
  </Grid>
</Window>

CodeBehind:{Window1.xaml.cs}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WPFSamples
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public abstract partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }
    }
}

派生クラス:{DisabledButtonWindow.cs}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace WPFSamples
{
    public sealed class DisabledButtonWindow : Window1
    {
        public DisabledButtonWindow()
        {
            Button1.IsEnabled = false;
        }
    }
}

wpfソース自体から継承することはできませんが、この「Window1」コントロールを他のすべての派生コントロールのテンプレートとして使用できます。

3
user1005465

これは、delegateを使用して実現できます。

基本的に、必要な機能をラップするインターフェイス(YourInterface)を作成し、ユーザーコントロールとクラスの両方にそのインターフェイスを実装させる必要があります。

次に、ユーザーコントロールがIYourInterface型のオブジェクトへの参照を持っていることを確認します。これにより、ユーザーコントロールがInterfaceのメソッドを呼び出そうとすると、クラスのメソッドが呼び出されます。

ユーザーコントロールとクラスの両方が同じインターフェイスを実装しているため、同じ種類のオブジェクトと見なすことができます。つまり、両方をIYourInterface型のオブジェクトのコレクションに入れることができます。これにより、必要な動作が得られます。

ASP.NETでは、クラスにabstract classの祖先を継承させることで、この手法を頻繁に使用しています。 WPFがこれをサポートしていない理由がわかりません。 :(

1
Maximiliano

私はあなたがこれを行うことができると思いますが、子クラスのxamlで参照するすべての関数とおそらく他のいくつかのものを再定義する必要があるでしょう。

IEの場合、基本クラスxamlでサブスクライブするボタンクリックイベントがある場合、子クラスのボタンクリックをオーバーライドし、基本クラスボタンクリックイベントを呼び出す必要があります。

私が作成しているのは私の同僚のコードなので、詳細は100%確実ではありませんが、これは将来これを実装することを検討しているすべての人にとって出発点になると考えました。

1
Matthew Beatty