【问题标题】:How to create second window that shows part of main window如何创建显示部分主窗口的第二个窗口
【发布时间】:2011-11-12 02:50:42
【问题描述】:

我有 WPF 功能区和网格的应用程序。而且我不仅需要在主应用程序窗口中显示此网格,还需要在第二个窗口中显示此网格。这个 Grid 包含很多元素,例如 ToggleButtons、TextBoxes、Images。 我的应用程序代码方案如下所示:

<ribbon:RibbonWindow
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        [...]
        xmlns:ribbon="clr-namespace:Microsoft.Windows.Controls.Ribbon;assembly=RibbonControlsLibrary"
        Title="MainWindow"
        x:Name="RibbonWindow"
        Height="870" Width="1000">

    <Grid x:Name="LayoutRoot">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <ribbon:Ribbon x:Name="Ribbon">
        [...]
        </ribbon:Ribbon>

        <Grid Background="#FF5C5C5C" Height="765" Width="986" Grid.Row="1" Margin="0,0,-2,-70" x:Name="MainGrid">
            <ToggleButton/>
            <TextBlock />
            <ToggleButton/>
            <Rectangle />
            [...]
         </Grid>

    </Grid>
</ribbon:RibbonWindow>

MainGrid 是我想在第二个窗口中显示的网格。它甚至可以是这个网格的唯一视图。但是当我在第一个窗口中更改某些内容时,例如在 TextBox 中写一些内容或单击 ToggleButton,我也需要让它在第二个屏幕上可见。

【问题讨论】:

  • 更新了我的答案,添加了一个演示和一些代码,希望对您有所帮助。

标签: c# .net wpf xaml desktop-application


【解决方案1】:

嗯,这会很棘手。我要做的是用 Grid 创建一个 UserControl,然后将一个 UserControl 放在 Window1 中,另一个放在 Window2 中。但是要同步 Window1-Grid 和 Window2-Grid 的状态,您必须将它们绑定到同一个对象。

编辑:在这里,为您准备了一个示例

第 1 步:Grid 放入UserControl,以便重复使用。

请注意,我将绑定上的UpdateSourceTrigger 属性设置为PropertyChanged,这会在用户键入时更新源对象,因此我们将看到Window2 中发生的变化,因为它们正在Window1 中发生。

CommonGrid.xaml

<UserControl x:Class="WindowSync.CommonGrid"
             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">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto"  />
        </Grid.RowDefinitions>
        <StackPanel Grid.Row="0" Orientation="Horizontal" Margin="5">
            <TextBlock Text="Name: " />
            <TextBox Width="200" Text="{Binding Name, UpdateSourceTrigger=PropertyChanged}" />
        </StackPanel>
        <StackPanel Grid.Row="1" Orientation="Horizontal" Margin="5">
            <CheckBox IsChecked="{Binding IsAdmin, UpdateSourceTrigger=PropertyChanged}" />
            <TextBlock Text=" Is Admin" />
        </StackPanel>
    </Grid>
</UserControl>

第 2 步:UserControl 放入所需的窗口中。

注意:你必须引用UserControl所在的命名空间,在这种情况下命名空间是WindowSync,这行让我们使用命名空间xmlns:app="clr-namespace:WindowSync"

Window1.xaml

<Window x:Class="WindowSync.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:app="clr-namespace:WindowSync"
        Title="Window 1" Height="200" Width="400">
    <app:CommonGrid x:Name="Window1Grid" />
</Window>

Windo1.xaml.cs

    public Window1()
    {
        InitializeComponent();
        Window1Grid.DataContext = Person.User; // bind the UserControl in Window1 to the an object
        new Window2().Show(); // create an instance of window 2 and show it
    }

Window2.xaml

<Window x:Class="WindowSync.Window2"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:app="clr-namespace:WindowSync"
        Title="Window 2" Height="200" Width="400">
    <app:CommonGrid x:Name="Window2Grid" />
</Window>

Window2.xaml.cs

    public Window2()
    {
        InitializeComponent();
        Window2Grid.DataContext = Person.User; // bind the UserControl in Window2 to the same object
    }

Person.cs

我刚刚为演示创建了一个名为 person 的随机对象。

注意:您必须在您的对象上实现INotifyPropertyChanged 接口,并在发生更改时引发适当的PropertyChanged 事件,这就是让我们同步两个网格的原因。 Window1 改变了一些东西,PropertyChanged 事件被触发,Window2 捡起它并做出改变。

public class Person : INotifyPropertyChanged
{
    public static Person User = new Person();

    #region Name
    private string _Name;
    public string Name
    {
        get { return _Name; }
        set
        {
            _Name = value;
            OnPropertyChanged("Name");
        }
    }
    #endregion

    #region IsAdmin
    private bool _IsAdmin;
    public bool IsAdmin
    {
        get { return _IsAdmin; }
        set
        {
            _IsAdmin = value;
            OnPropertyChanged("IsAdmin");
        }
    }
    #endregion

    #region INotifyPropertyChanged
    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string property)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(property));
    }
    #endregion
}

无论如何,我希望这对你有所帮助。如果您遇到困难,我上传了项目的压缩版本。 http://www.mediafire.com/?yv84xbben6tjdy7

祝你好运。

【讨论】:

  • 非常感谢这段代码!它对于“检查”操作非常有效。但我在绑定 IsEnabled 属性时遇到问题。我已经将绑定添加到这样的控件: 但它不起作用。当我运行应用程序 ToggleButton 时禁用,并且当我更改其状态(使用函数)时,当前状态不会转移到第二个窗口。
  • 嘿,您是否正在为该属性引发 PropertyChanged 事件?在此处发布您的完整代码,我会尽力帮助您。我现在要出去,深夜回来,到时候我看看。
  • 我添加了 Mode=TwoWay,现在它工作得很好。非常感谢您的帮助!
猜你喜欢
  • 2019-06-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-20
相关资源
最近更新 更多