2016-01-21 60 views
0

之间的数据我有一个主窗口并且在主窗口的按钮打开ClientWindow。WPF传递克隆的Windows

private void btnMakeClient_Click(object sender, RoutedEventArgs e) 
     { 
      ClientWindow window = new ClientWindow();   
      window.Show(); 
     } 

Forexample;如果我3次点击,则会打开3个ClientWindow(chatWindow)。 如何在这些克隆窗口之间传递数据(文本)?我的意思是我写“你好吗?”在一个ClientWindow(chatWindow)中,它也出现在另一个窗口中。

我想,如果我通过从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(); 
     } 
    } 

ClientWindow:

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); 
    } 
} 
+0

@VisualBean在Observer模式对象的情况下将主窗口,可以通知ChildWindows(观察者)如果事情在它的变化。在这个要求中,其中一个观察员将改变状态而不是主题。 – niksofteng

回答

1

这就是MVVM眼前一亮。创建一个ViewModel对象,该对象包含一个String属性和一个Command以向该属性添加文本,然后在客户端窗口中调用该命令并添加文本作为参数。

请注意,我用DelegateCommand描述here,但你也可以使用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(); 
    } 
} 

ClientWindow 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

如果你不想设置的DataContext你可以使用另一个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(); 
} 
+0

是否有任何可能的解决方案没有datacontext?谢谢 –

+0

@AtilaAlan你可以为此创建一个DP。或者是一个通知OnPropertyChanged的简单属性。编辑我的答案 – nkoniishvt

0

您可以用文本属性消息创建一个类,这个类执行INotifyPropertyChanged。然后将该类的一个实例存储在MainWindow中,并将其传递给ClientWindow的构造函数。将其设置为DataContext并创建对Text属性的绑定(例如,在TextBox中)。当你更新Text属性时,其他窗口会看到这个改变。

+0

这应该是一个评论,除非您可以发布工作代码来支持您的解决方案。代码也是必需的,因为您正在使用MVVM方式进行交互,而OP在Win Forms方式中正在执行WPF。 – niksofteng

+0

@nikhilvartak我只是想给一个正确的方向。我认为它是更有用的,那么一个完整的解决方案,你可以复制粘贴(特别是对于看起来像初学者的作者) – chameleon86