WPFのmainWindowのボタンやテキストボックスなどのコントロールにアクセスしたいのですが、これはできません。
Windowsフォームアプリケーションではとても簡単です。そのコントロールの修飾子をTrueに設定して、そのmainWindowのインスタンスからそのコントロールに到達できますが、WPFではパブリックコントロールを宣言できません。これどうやってするの?
別のWPFフォームのコントロールにアクセスするには、そのコントロールをパブリックとして宣言する必要があります。 WPFのコントロールの既定の宣言はパブリックですが、次のコードで指定できます。
<TextBox x:Name="textBox1" x:FieldModifier="public" />
その後、アプリケーションのすべてのアクティブなウィンドウを検索して、次のようなコントロールを持つウィンドウを見つけることができます。
foreach (Window window in Application.Current.Windows)
{
if (window.GetType() == typeof(Window1))
{
(window as Window1).textBox1.Text = "I changed it from another window";
}
}
残念ながら、WPFの基本はデータバインディングです。それ以外の方法でそれを行うことは、「きめ細かさを損なう」ことであり、悪い習慣であり、通常、コードを作成して理解するのは桁違いに複雑です。
目前の問題として、ビュー間で共有するデータがある場合(それが1つのビューのみであっても)、データを表すプロパティを含むビューモデルクラスを作成し、ビューのプロパティにバインドします。
コードでは、ビューモデルクラスのみを管理し、ビジュアルコントロールとビジュアル構成を使用して実際のビューに触れないでください。
WPFでは、WindowをMainWindowとしてキャストする必要があることがわかりました。
複雑に見えますが非常に簡単ですただし、ベストプラクティスではない可能性があります
MainWindowにLabel1、Button1があり、UIと呼ばれるユーザーインターフェイスに関連するすべてを処理するクラスがあるとします。
次のものを用意できます。
MainWindow Class:
namespace WpfApplication1
{
public partial class MainWindow : Window
{
UI ui = null;
//Here, "null" prevents an automatic instantiation of the class,
//which may raise a Stack Overflow Exception or not.
//If you're creating controls such as TextBoxes, Labels, Buttons...
public MainWindow()
{
InitializeComponent(); //This starts all controls created with the XAML Designer.
ui = new UI(); //Now we can safely create an instantiation of our UI class.
ui.Start();
}
}
}
Iクラス:
namespace WpfApplication1
{
public class UI
{
MainWindow Form = Application.Current.Windows[0] as MainWindow;
//Bear in mind the array! Ensure it's the correct Window you're trying to catch.
public void Start()
{
Form.Label1.Content = "Yay! You made it!";
Form.Top = 0;
Form.Button1.Width = 50;
//Et voilá! You have now access to the MainWindow and all it's controls
//from a separate class/file!
CreateLabel(text, count); //Creating a control to be added to "Form".
}
private void CreateLabel(string Text, int Count)
{
Label aLabel = new Label();
aLabel.Name = Text.Replace(" ", "") + "Label";
aLabel.Content = Text + ": ";
aLabel.HorizontalAlignment = HorizontalAlignment.Right;
aLabel.VerticalAlignment = VerticalAlignment.Center;
aLabel.Margin = new Thickness(0);
aLabel.FontFamily = Form.DIN;
aLabel.FontSize = 29.333;
Grid.SetRow(aLabel, Count);
Grid.SetColumn(aLabel, 0);
Form.MainGrid.Children.Add(aLabel); //Haha! We're adding it to a Grid in "Form"!
}
}
}
var targetWindow = Application.Current.Windows.Cast<Window>().FirstOrDefault(window => window is principal) as principal;
targetWindow .BssAcesso.Background = Brushes.Transparent;
現在のウィンドウからそのコントロールを呼び出すだけです。
targetWindow.ABUTTON.Background = Brushes.Transparent;
wpfで別のウィンドウから1つのウィンドウのコントロール(richtextbox)にアクセスするにはどうすればよいですか?
WPFを開始したときも、これに苦労していました。しかし、古き良きwinフォームアプローチ(VB.NETのコーディング、申し訳ありません)に似た良い方法が見つかりました。以前に言ったことを追加します:
アクティブウィンドウのモジュールまたは別のクラスからオブジェクトのプロパティを直接変更するには:
_Public Class Whatever
Public Sub ChangeObjProperties()
' Here the window is indexed in case of multiple instances of the same
' window could possibly be open at any given time.. otherwise just use 0
Dim w As MainWindow = Application.Current.Windows(0)
w.Button1.Content = "Anything"
End Sub
End Class
_
ChangeObjProperties()
をコードで呼び出す前に、Whatever
をインスタンス化する必要があります。
また、オブジェクトのアクセシビリティに関してXAMLでの命名について心配する必要はありません。
次のようにコントロールを宣言して公開します。
<TextBox x:Name="textBox1" x:FieldModifier="public" />
その後、別のコントロールからアクセスできます。
コントロールのデフォルトの宣言は非公開、内部、そして非公開です!
したがって、同じアセンブリ内からのコントロールへのアクセスが許可されます。別のアセンブリからwpfフォームのコントロールにアクセスする場合は、修飾子属性x:FieldModifier = "public"を使用するか、Jeanが提案したメソッドを使用する必要があります。