WPF 在克隆窗口之间传递数据
本文关键字:数据 之间 窗口 WPF | 更新日期: 2023-09-27 18:31:16
我有一个MainWindow,MainWindow中有一个按钮可以打开ClientWindow。
private void btnMakeClient_Click(object sender, RoutedEventArgs e)
{
ClientWindow window = new ClientWindow();
window.Show();
}
例如,如果我点击 3 次,那么它会打开 3 个客户端窗口(chatWindow)。如何在这些克隆窗口之间传递数据(文本)?我的意思是我在ClientWindow(chatWindow)中写"嗨,你好吗?",它也出现在另一个窗口中。
我认为如果我使用 MainWindow 构造函数从 ClientWindow 传递数据(文本)并使用 ClientWindow 构造函数将其取回,则会解决我的问题,但事实并非如此。这是我的代码
主窗口:
public partial class MainWindow : Window
{
public string TextContent { get; set; }
public MainWindow()
{
InitializeComponent();
}
public MainWindow(string txtContext)
{
InitializeComponent();
TextContent = txtContext;
ClientWindow window = new ClientWindow(TextContent);
}
private void btnMakeClient_Click(object sender, RoutedEventArgs e)
{
ClientWindow window = new ClientWindow();
window.Show();
}
}
客户端窗口:
public partial class ClientWindow : Window
{
public string Chatcontent { get; set; }
public ClientWindow()
{
InitializeComponent();
}
public ClientWindow(string chatContent)
{
InitializeComponent();
Chatcontent = chatContent;
if (chatContent != string.Empty)
{
this.txtContent.Text += Environment.NewLine + Chatcontent;
txtChat.Clear();
}
}
private void btnSend_Click(object sender, RoutedEventArgs e)
{
MainWindow window = new MainWindow(txtChat.Text);
}
}
这就是 MVVM 闪耀的地方。创建一个 ViewModel 对象,其中包含一个 String 属性和一个用于向此属性添加文本的命令,然后在客户端窗口中,只需使用要添加为参数的文本调用此命令。
请注意,我使用此处所述的 DelegateCommand,但您也可以使用 RelayCommand。
视图模型
public class YourViewModel : INotifyPropertyChanged {
private String _textContent;
public String TextContent {
get {return _textContent;}
set {
_textContent = value;
OnPropertyChanged("TextContent");
}
}
private DelegateCommand _cmdAddTextToChat;
/// <summary>
/// Add text to TextContent
/// </summary>
public DelegateCommand CmdAddTextToChat {
get { return _cmdAddTextToChat ?? (_cmdAddTextToChat = new DelegateCommand(AddTextToChat)); }
}
private void AddTextToChat(Object parameter) {
TextContent += (String)parameter;
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName) {
var handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
public partial class MainWindow : Window
{
private YourViewModel _vm = new YourViewModel ();
public MainWindow()
{
InitializeComponent();
}
public MainWindow(string txtContext)
{
InitializeComponent();
_vm.TextContent = txtContext;
ClientWindow window = new ClientWindow() {DataContext = _vm};
}
private void btnMakeClient_Click(object sender, RoutedEventArgs e)
{
ClientWindow window = new ClientWindow() {DataContext = _vm};
window.Show();
}
}
public partial class ClientWindow : Window
public ClientWindow()
{
InitializeComponent();
}
}
客户端窗口 xaml:
<DockPanel>
<StackPanel DockPanel.Dock="Bottom" Orientation="Horizontal">
<TextBox x:Name="InputTextBox"/>
<Button Command="{Binding CmdAddTextToChat, Mode=OneWay}" CommandParameter="{Binding ElementName=InputTextBox, Path=Text}">
</StackPanel>
<TextBlock DockPanel.Dock="Top" Text="{Binding TextContent, Mode=OneWay}"/>
</DockPanel>
编辑:没有数据上下文
如果您不想设置 DataContext,您可以使用另一个 DP(可以使用 Tag,也可以创建一个新 DP):
#region ViewModelObject
public YourViewModel ViewModelObject
{
get { return (YourViewModel)GetValue(ViewModelObjectProperty); }
set { SetValue(ViewModelObjectProperty, value); }
}
private readonly static FrameworkPropertyMetadata ViewModelObjectMetadata = new FrameworkPropertyMetadata {
};
public static readonly DependencyProperty ViewModelObjectProperty =
DependencyProperty.Register("ViewModelObject", typeof(YourViewModel), typeof(ClientWindow), ViewModelObjectMetadata);
#endregion
在您的点击事件中
private void btnMakeClient_Click(object sender, RoutedEventArgs e)
{
ClientWindow window = new ClientWindow() {YourViewModelObject = _vm};
window.Show();
}
您可以使用 Text 属性为消息创建一个类,并在此类中实现 INotifyPropertyChanged。然后将此类的实例存储在 MainWindow 中,并将其传递给 ClientWindow 的构造函数。将其设置为 DataContext 并创建与 Text 属性的绑定(例如,在 TextBox 中)。更新 Text 属性时,其他窗口将看到此更改。