none
WPFにて、別のXamlファイルのコントロールを扱うには RRS feed

  • 質問

  • こんにちは、Xamlについて質問です。

    例えば、a.xamlにtextboxを記述した場合、a.xaml.csではそのtextboxのnameを利用すればコントロールを扱うことができますが、別のファイルb.csというクラスファイルからtextboxを同様に扱おうとするとエラーが出てしまいます。

    このように、別のcsファイルからxamlのコントロールを扱うことはできないのでしょうか。

    2016年10月10日 3:26

回答

  • buttonはMainWindowがインスタンス化(newによって実体化)されるときに一緒に実体化されます。
    このインスタンス化は何個でも作れます(MainWinowを何個もnewで作ることができる)から、そこに含まれるbuttonも同じように何個も作られます。
    逆に言うとMainWindowが無い状態では、その中にあるbuttonは存在しないので、操作することはできません。
    さらにMainWindow以外のWindowなどでbuttonという名前を付けることもできます。

    ですからClass1内で単純にbuttonとしてもどのbuttonかわからないのです。
    そのため、どのbuttonかわかるようにしてやらなければなりません。

    using System.Windows;
    namespace WpfApplication1
    {
        public partial class MainWindow : System.Windows.Window
        {
            public MainWindow()
            {
                InitializeComponent();
    
                //thisで自分(MainWindow)の中にあるbuttonであると明示する
                this.button.Content = "hoge";
            }
    
            private void button1_Click(object sender, RoutedEventArgs e)
            {
                Class1 c1 = new Class1();
                c1.Test1(this);//Class1にMainWindow自身を渡すことでどのMainWindowにあるかはっきりさせる
            }
    
            private void button2_Click(object sender, RoutedEventArgs e)
            {
                Class1 c1 = new Class1();
                c1.TargetWindow = this;//c1で操作することになるMainWindowをあらかじめ設定しておく場合
                c1.Test2();//この場合はTargetWindowとして伝えてあるので引数で渡さなくてもよくなる
            }
    
            private void button3_Click(object sender, RoutedEventArgs e)
            {
                Class1 c1 = new Class1();
                MainWindow mainWindow2 = new MainWindow() { Title = "2個目のウィンドウ" };
                c1.Test1(mainWindow2);//今表示されているMainWindowではないMainWindowを操作対象にもできます。
                mainWindow2.Show();
            }
    
    
            public static MainWindow Default;// static変数の場所や名前は自由にできます
            private void button4_Click(object sender, RoutedEventArgs e)
            {
                //操作対象のMainWindowが一つしか作らないことが確定されてるのであれば
                //static変数を介する方法もあります。(ただし、できれば使わない方が良い)
                if (Default != null)
                {
                    Default=this;//予めstatic変数にMainWindowを設定しておく必要があります
                }
                
                Class1 c1 = new Class1();
                c1.Test4();
            }
        }
    
    
        class Class1
        {
            public void Test1(MainWindow mw)
            {
                //引数mwで伝えられたMainWindowを対象にする方法
                mw.button.Content = "hoge1";
            }
    
            public MainWindow TargetWindow;//操作対象をClass1で知るための変数(変数名は自由に付けられます。)
            public void Test2()
            {
                //予め対象のTargetWindowに対象のMainWindowはを設定しておく必要があります
                this.TargetWindow.button.Content = "hoge2";
            }
    
            public void Test4()
            {
                //static変数に設定されているMainWindowを対象にする方法
                //予めMainWindowクラスのDefaultという名前のstatic変数に設定しておいた場合
                MainWindow.Default.button.Content = "hoge4";
            }
        }
    }


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 編集済み gekkaMVP 2016年10月10日 10:33
    • 回答としてマーク TakumaNakgame 2016年10月11日 22:23
    2016年10月10日 10:23

すべての返信

  • どのようなエラーが出るのでしょうか?

    定義されているのがWindowやPageやUserControlで、ビルド時に「定義が含まれておらず」の様なエラーであれば、x:FieldModifierをpublicにしてやれば見つけられるようにになるかもしれません。

    <TextBox Name="textBox1" x:FieldModifier="public"  />




    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    2016年10月10日 5:37
  • 例えば、以下のようなソースの場合、class1.csにて「buttonは現在のコンテキストに存在しません。」とエラーが出ます。
    このように、class1.csにてbuttonを使いたい場合はどのようにしたら良いのでしょうか。

    file: MainWindow.xaml
    
    <Window x:Class="WpfApplication1.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WpfApplication1"
            mc:Ignorable="d"
            Title="MainWindow" Height="350" Width="525">
        <Grid>
             <Button x:Name="button" Content="Button" HorizontalAlignment="Left" Margin="307,166,0,0" VerticalAlignment="Top" Width="75" x:FieldModifier="public"/>
        </Grid>
    </Window>
    
    
    ----------------------------------------------------------------
    file: MainWindow.xaml.cs
    
    using System.Windows;
    
    namespace WpfApplication1
    {
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
                button.Content = "hoge";
            }
        }
    }
    
    
    ----------------------------------------------------------------
    file: Class1.cs
    
    namespace WpfApplication1
    {
        class Class1
        {
            button.Content = "hoge";
        }
    }
    

    2016年10月10日 6:44
  • buttonはMainWindowがインスタンス化(newによって実体化)されるときに一緒に実体化されます。
    このインスタンス化は何個でも作れます(MainWinowを何個もnewで作ることができる)から、そこに含まれるbuttonも同じように何個も作られます。
    逆に言うとMainWindowが無い状態では、その中にあるbuttonは存在しないので、操作することはできません。
    さらにMainWindow以外のWindowなどでbuttonという名前を付けることもできます。

    ですからClass1内で単純にbuttonとしてもどのbuttonかわからないのです。
    そのため、どのbuttonかわかるようにしてやらなければなりません。

    using System.Windows;
    namespace WpfApplication1
    {
        public partial class MainWindow : System.Windows.Window
        {
            public MainWindow()
            {
                InitializeComponent();
    
                //thisで自分(MainWindow)の中にあるbuttonであると明示する
                this.button.Content = "hoge";
            }
    
            private void button1_Click(object sender, RoutedEventArgs e)
            {
                Class1 c1 = new Class1();
                c1.Test1(this);//Class1にMainWindow自身を渡すことでどのMainWindowにあるかはっきりさせる
            }
    
            private void button2_Click(object sender, RoutedEventArgs e)
            {
                Class1 c1 = new Class1();
                c1.TargetWindow = this;//c1で操作することになるMainWindowをあらかじめ設定しておく場合
                c1.Test2();//この場合はTargetWindowとして伝えてあるので引数で渡さなくてもよくなる
            }
    
            private void button3_Click(object sender, RoutedEventArgs e)
            {
                Class1 c1 = new Class1();
                MainWindow mainWindow2 = new MainWindow() { Title = "2個目のウィンドウ" };
                c1.Test1(mainWindow2);//今表示されているMainWindowではないMainWindowを操作対象にもできます。
                mainWindow2.Show();
            }
    
    
            public static MainWindow Default;// static変数の場所や名前は自由にできます
            private void button4_Click(object sender, RoutedEventArgs e)
            {
                //操作対象のMainWindowが一つしか作らないことが確定されてるのであれば
                //static変数を介する方法もあります。(ただし、できれば使わない方が良い)
                if (Default != null)
                {
                    Default=this;//予めstatic変数にMainWindowを設定しておく必要があります
                }
                
                Class1 c1 = new Class1();
                c1.Test4();
            }
        }
    
    
        class Class1
        {
            public void Test1(MainWindow mw)
            {
                //引数mwで伝えられたMainWindowを対象にする方法
                mw.button.Content = "hoge1";
            }
    
            public MainWindow TargetWindow;//操作対象をClass1で知るための変数(変数名は自由に付けられます。)
            public void Test2()
            {
                //予め対象のTargetWindowに対象のMainWindowはを設定しておく必要があります
                this.TargetWindow.button.Content = "hoge2";
            }
    
            public void Test4()
            {
                //static変数に設定されているMainWindowを対象にする方法
                //予めMainWindowクラスのDefaultという名前のstatic変数に設定しておいた場合
                MainWindow.Default.button.Content = "hoge4";
            }
        }
    }


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 編集済み gekkaMVP 2016年10月10日 10:33
    • 回答としてマーク TakumaNakgame 2016年10月11日 22:23
    2016年10月10日 10:23
  • 無事、扱うことができました。
    ありがとうございます。

    2016年10月11日 22:29