3

さて、私はユーザーコントロール(ビュー)を継承するコントロールを持っており、ユーザーコントロール(ベースコントロール)を使用するときにそれを使用しています。

MessageBox.Show(this.GetType().ToString());

実行時と設計時に異なるメッセージを取得し、設計時にビューを取得し、実行時にビューを継承する xaml ファイルのクラス名を取得します...

基本クラスの代わりに、設計時に継承クラスの型を取得するにはどうすればよいですか?

ここにいくつかのコードがあります:

まず、ビュークラスがあります

public class View : UserControl
{
    public override void OnApplyTemplate()
    {
        MessageBox.Show(this.GetType().ToString());
        base.OnApplyTemplate();
    }
}

次に、XAML ファイルがあります。

<local:View x:Class="WpfApplication2.Test"
             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" 
             xmlns:local="clr-namespace:WpfApplication2"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>

    </Grid>
</local:View>

VisualStudio 2010 で "WpfApplication2.Test" をコンパイルして開くと、"WpfApplication2.View" というメッセージ ボックスが表示されます。

しかし、Test コントロールを MainWindow に配置して Run(F5) を押すと、WpfApplication2.Test が得られます。私が望むのは、実行時と同じ応答をデザイン時にもることです...

4

4 に答える 4

3

問題は、Visual Studio 2010のXAMLデザイナーが、分離コードで宣言された実際のクラスをインスタンス化しないことです。代わりに、基本クラスのみをインスタンス化します。

考えてみると、XAMLを変更すると、XAMLから作成された別の部分と組み合わされた部分クラスであるため、コードビハインドで宣言されたクラスそのものが実際に変更されます。したがって、デザイナはクラスのインスタンスを作成できません。それはまだ作成中です。

Visual Studio自体と何らかの形で相互作用して、実際にどのファイルが設計されているかを尋ねるコードを記述しなければ、目的を達成できるとは思いません。

DesignerProperties.GetIsInDesignMode()のチェックを使用して、少なくともコードを保護できます。

関連情報については、次のリンクを参照してください。

WPFDesignerの読み込みエラーのトラブルシューティング

VS 2008 XAML DesignerビューがGUIをレンダリングしようとすると、何が呼び出されますか?

WPF Designer(Cider)ではそれを行わないでください!

于 2010-09-02T21:51:04.213 に答える
1

VS2010 Designer (Cider) は、派生コントロールを設計するときに、基本クラスのインスタンスをインスタンス化しています。それについてあなたができることは何もありません。

于 2010-09-03T05:21:38.580 に答える
1

Petoj さん、型の名前を知りたい理由と、設計時に異なると問題が発生する理由を自問して説明する必要があると思います。あなたが風車と戦っていて、私の意見では合理的な答えが得られない場合を除きます.

更新 — 簡単な回避策の擬似コード:

if (IsDesignTime)
   use this.GetType()
else
   use this.GetType().BaseType

更新 2:設計時に、設計中の子孫クラスの名前を取得する方法がありません。問題は、実際のクラスの名前に依存するのではなく、おそらく別の方法で解決されるはずです。

于 2010-09-03T18:23:13.047 に答える
0

私はまだ WPF を学習しているので、これはおそらくあなたが探しているものではありません。

設計時および実行時、 this.GetType().ToString(); メッセージボックスに「WpfApplication2.View」が返されます。

したがって、両方のモードでビューが返されます。私はあなたのコードにわずかな変更を加えたことを述べます。

namespace WpfApplication2
{
    /// <summary>
    /// Interaction logic for View.xaml
    /// </summary>
    public partial class View : UserControl
    {
        public override void OnApplyTemplate()
        {
            MessageBox.Show(this.GetType().ToString());
            base.OnApplyTemplate();
        }
    }
}

XAML は明らかに .cs ファイルから分割されているため、単なるクラスではなく部分クラスとしてマークしています。私はこれが問題になるとは思わないでしょう。

于 2010-09-02T21:31:11.093 に答える