Reputation: 33
Not terribly familiar with WPF and C# so if this is blatantly wrong, please correct me. Working in VSExpress2015 .NET Framework 4.5. I'm heavily simplifying my code below, so know that namespace/library references are there.
Say I have a window with a Button and ContentControl inside:
<Window x:Class="Project.MainWindow">
<Grid>
<Button Name="Submit_Btn" Click="Submit_Btn_Click">
<ContentControl Name="MainContentControl">
</Grid>
</Window>
I also have several user control files in my project with XAML that looks something like this:
<UserControl x:Class="Project.UserControl1">
<Grid>
<TextBox Name="TxtBox1">
</Grid>
</Usercontrol>
I have code in the backend of my MainWindow to dynamically load the appropriate UserControl into the "MainContentControl" object. However, I want to reference the objects inside of the currently loaded UserControl from the MainWindow's Submit_Btn_Click function. For example, in MainWindow.cs, do something like this:
private void Submit_Btn_Click(object sender, RoutedEventArgs e)
{
if(MainContentControl is currently loaded with UserControl1)
Do_Something_Function(MainContentControl.TxtBox1.Text);
}
The main problem here is I don't know how to call the TextBox1 element from within the parent MainWindow's scope. I'm also not sure how to validate the if condition (confirming the control is currently loaded). Does anyone know of a way to think about this differently or even directly reference the object (despite that probably not being a great idea)?
--
I'm not using/familiar with MVVM at all (yet), and I'm not particularly concerned with optimal performance as this is a one off temporary project that will soon die and be re-worked. I've read ways how to access the data in a parent window from a child, but I didn't find scenarios that really matched up with this.
Once again, I'm still familiarizing myself with C#, WPF and general coding practices (it's been a couple years), so if using a ContentControl or UserControl here isn't optimal, (or mixing the two doesn't make sense) that information would be greatly appreciated; however, in this scenario, I'm more concerned with just getting this working until I can learn more proper techniques later.
Upvotes: 3
Views: 5130
Reputation: 797
You can use the LogicalTreeHelper
to search by name.
So for your example to access TextBox1
var txtBox = LogicalTreeHelper.FindLogicalNode(MainContentControl, "TextBox1") as TextBox;
Do_Something_Function(txtBox?.Text);
Upvotes: 2
Reputation: 91
It definitely looks like the design should be improved, but just to get this working you can do the following:
private void Submit_Btn_Click(object sender, RoutedEventArgs e)
{
var controlAsUserControl1 = MainContentControl.Content as UserControl1;
if (controlAsUserControl1 != null)
{
Debug.WriteLine(controlAsUserControl1.TxtBox1.Text);
}
}
Upvotes: 0
Reputation: 680
Instead of trying to access the TextBox inside the UserControl, you can expose properties and methods on the UserControl itself to interact with what's inside. In your case, you could add a property that returns the current value of TextBox.Text. You can also add dependency properties to facilitate binding.
Upvotes: 1