One way to do this is that you publish an event on the user control and wire that event on the window level in order to receive events from the control. When an event is received, call a method on the other control to set the value.
Consider the following example:
Class to hold event arguments
public class SomeChangeEventArgs : System.EventArgs {
public string TextValue { get; set; }
}
User control XAML
<UserControl x:Class="MyNamespace.UserControl1"
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:MyNamespace"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="300">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBox Grid.Row="0" x:Name="MyTextBox"/>
<Button Grid.Row="1" x:Name="TheButton" Content="Press me..." Click="TheButton_Click"/>
</Grid>
</UserControl>
User control cs
using System;
using System.Windows;
using System.Windows.Controls;
namespace MyNamespace {
public partial class UserControl1 : UserControl {
public event EventHandler<SomeChangeEventArgs> SomethingHasChanged;
public UserControl1() {
InitializeComponent();
}
private void TheButton_Click(object sender, RoutedEventArgs e) {
this.SomethingHasChanged?.Invoke(
this, new SomeChangeEventArgs() {
TextValue = this.MyTextBox.Text
}
);
}
public void SetTextValue(string newText) {
this.MyTextBox.Text = newText;
}
}
}
Main window XAML
<Window x:Class="MyNamespace.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:MyNamespace"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<local:UserControl1 Grid.Column="0" x:Name="FirstControl" SomethingHasChanged="First_SomethingHasChanged"/>
<local:UserControl1 Grid.Column="1" x:Name="SecondControl" SomethingHasChanged="Second_SomethingHasChanged"/>
</Grid>
</Window>
And the main window cs
using System.Windows;
namespace MyNamespace {
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
}
private void First_SomethingHasChanged(object sender, SomeChangeEventArgs e) {
this.SecondControl.SetTextValue(e.TextValue);
}
private void Second_SomethingHasChanged(object sender, SomeChangeEventArgs e) {
this.FirstControl.SetTextValue(e.TextValue);
}
}
}