I am trying to write a WPF application that takes an user input in one UserControl and then shows it in another UserControl, on a different Page. To capture user input in SetupLocation, I use a TextBox which has a TwoWay binding to a LocationSettings object, which currently has only one attribute, LocationName. The other Page includes an UserControl called ShowResult, and it has a OneWay binding to the LocationSettings object.
I am using .NET Framework v4.7.2 and Visual Studio 2019.
However:
What am I missing?
This is the XAML for UserControl called SetupLocation (used to input the data):
<StackPanel Orientation="Vertical" Margin="10"
VerticalAlignment="Top">
<StackPanel.Resources>
<ObjectDataProvider x:Key="locationInput" ObjectType="{x:Type classes:LocationSettings}"/>
</StackPanel.Resources>
<TextBox x:Name="LocationName"
<TextBox.Text>
<Binding Source="{StaticResource locationInput}"
Path="LocationName"
Mode="TwoWay"
UpdateSourceTrigger="Explicit"/>
</TextBox.Text>
</TextBox>
<Button x:Name="addParameters"
Content="Set"
Click="addParameters_Click"/>
</StackPanel>
Code behind for SetupLocation:
public partial class SetupLocation : UserControl
{
public SetupLocation()
{
InitializeComponent();
}
private void addParameters_Click(object sender, RoutedEventArgs e)
{
BindingExpression be = LocationName.GetBindingExpression(TextBox.TextProperty);
be.UpdateSource();
}
}
The XAML for UserControl (part of a different Page than SetupLocation) ShowResult that should show what was entered in the SetupLocation:
<StackPanel>
<StackPanel.Resources>
<ObjectDataProvider x:Key="locationInput" ObjectType="{x:Type classes:LocationSettings}"/>
</StackPanel.Resources>
<Label FontSize="18" Foreground="Green">
<Label.Content>
<Binding Source="{StaticResource locationInput}"
Path="LocationName"
/>
</Label.Content>
</Label>
</StackPanel>
The class LocationSettings that contains the LocationName variable which I need to pass between the two usercontrols.
public class LocationSettings : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string _locationName;
public string LocationName
{
get {
return _locationName;
}
set {
_locationName = value;
OnPropertyChanged();
}
}
public LocationSettings()
{
// _locationName = "Nowhere really";
}
protected void OnPropertyChanged([CallerMemberName] string tmp = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(tmp));
}
}
MainWindow.xaml:
public partial class MainWindow : Window
{
public LocationSettings DefaultSettings;
public MainWindow()
{
InitializeComponent();
DefaultSettings = new LocationSettings();
}
Do you know what the following code using ObjectDataProvider
does? It creates an object of type LocationSettings
in xaml. Since you do this in both user controls, you create 2 objects (1 in each user control) so each user control is binding to different objects.
<StackPanel.Resources>
<ObjectDataProvider x:Key="locationInput" ObjectType="{x:Type classes:LocationSettings}"/>
</StackPanel.Resources>
As a possible solution, I am assuming your MainWindow
hosts both user controls. If this is the case, set the DataContext
of your main window to the LocationSettings
you create in the constructor rather than using an ObjectDataProvider
in the user controls. The parent (your MainWindow
) data context will be inherited by both user controls.
public partial class MainWindow : Window
{
// I changed this to a "getter".
// The way you declared it would make it a public "field" and not a "property"
public LocationSettings DefaultSettings { get; }
public MainWindow()
{
InitializeComponent();
DefaultSettings = new LocationSettings();
DataContext = DefaultSettings; // Set the data context of the main window
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.