WPF-MVVM-将窗口标题绑定到属性

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14397728/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 07:06:41  来源:igfitidea点击:

WPF-MVVM-Bind window title to property

c#wpfmvvmbinding

提问by MikeR

My client application can connect to different server applications, therefore I would like to add the connection information to the window title dynamically. The title is bound to a property of the ViewModeland its getis called after starting the app, but than it doesn't get updated anymore, while other controls in the window are still working properly.

我的客户端应用程序可以连接到不同的服务器应用程序,因此我想动态地将连接信息添加到窗口标题中。标题绑定到的属性,ViewModelget在启动应用程序后被调用,但它不再更新,而窗口中的其他控件仍然正常工作。

Here is the XAML:

这是XAML

<Window x:Class="MyApp.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"
    mc:Ignorable="d"
    xmlns:localVM="clr-namespace:MyApp.ViewModels"
    xmlns:local="clr-namespace:MyApp"
    WindowStartupLocation="CenterScreen"
    Title="{Binding Path=AppTitle}"
    Height="459"
    Width="810">
<Window.Resources>
    [...]
    <localVM:MainWindowViewModel x:Key="Windows1ViewModel" />
</Window.Resources>
<Grid DataContext="{StaticResource Windows1ViewModel}">
    <Grid.RowDefinitions>
        <RowDefinition Height="30" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <Canvas Grid.Row="0">
        <Menu DockPanel.Dock="Top" ItemsSource="{Binding Path=Menu}"/>
        <Label Content="{Binding Path=ConnectionProperty}" Canvas.Right="0" Canvas.Bottom="0"/>
    </Canvas>
 </Grid>
</Window>

The Titleis bound to AppTitle, while Labelis bound to ConnectionProperty, which is working fine. In the XAML.csI set the ViewModelto the DataContextof the View:

The Titleis bound to AppTitle, while Labelis bound to ConnectionProperty,工作正常。在XAML.cs我设置ViewModelDataContextView

public MainWindow()
{
    InitializeComponent();
    DataContext = new MainWindowViewModel();
}

The constructor of the MainWindowViewModel:

的构造函数MainWindowViewModel

public MainWindowViewModel()
{
    MenuItemViewModel server = new MenuItemViewModel { Text = ServerMenu };
    Menu.Add(server);
    AppTitle = "My application title";
    SetConnectionMenuEntry(false);
    //[.. dynamically build my menu ..]
}

After starting the application, the Titleis shown correctly. Then I connect to a server:

启动应用程序后,Title显示正确。然后我连接到服务器:

private void ConnectToServer()
{
    //[.. connect to server ..]
    if (connected)
    {
        SetConnectionMenuEntry(true);
        ConnectionProperty = " - connected to " + serverProxy.url;
        AppTitle  = appTitle + connectionProperty;
    }
}

After this, the Titleremains the same, while the Labelgets the ConnectionPropertyvalue.

在此之后, theTitle保持不变,而 theLabel获取ConnectionProperty值。

Here is the definition of both properties, which is nearly identical:

这是两个属性的定义,几乎相同:

    private string appTitle;
    public string AppTitle 
    {
        get { return appTitle; }
        set 
        {
            if (this.appTitle != value)
            {
                this.appTitle = value;
                RaisePropertyChanged(() => AppTitle);
            }
        }
    }

    private string connectionProperty = "";
    public string ConnectionProperty
    {
        get { return this.connectionProperty; }
        set
        {
            if (this.connectionProperty != value)
            {
                this.connectionProperty = value;
                RaisePropertyChanged(() => ConnectionProperty);
            }
        }
    }

Any idea why the Titleis not updated, but the Label?

知道为什么Title没有更新,而是Label

采纳答案by Aphelion

You have the Windows1ViewModelin the Grid.Resources, however you create a new DataContext for the window from code. You have two instances of the ViewModel this way.

您在Windows1ViewModel中有Grid.Resources,但是您从代码中为窗口创建了一个新的 DataContext。通过这种方式,您有两个 ViewModel 实例。

回答by Hugo Dozois

As stated by the original poster of the question:

正如问题的原始海报所述:



I commented out the lines I needed to remove to make it work properly :

我注释掉了需要删除以使其正常工作的行:

<Window x:Class="MyApp.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"
    mc:Ignorable="d"
    xmlns:localVM="clr-namespace:MyApp.ViewModels"
    xmlns:local="clr-namespace:MyApp"
    WindowStartupLocation="CenterScreen"
    Title="{Binding Path=AppTitle}"
    Height="459"
    Width="810">
<Window.Resources>
    [...]
    <!-- <localVM:MainWindowViewModel x:Key="Windows1ViewModel" /> [Edit: 2 times set] -->
</Window.Resources>
<Grid> <!-- Edit removed: DataContext="{StaticResource Windows1ViewModel}" -->
    <Grid.RowDefinitions>
        <RowDefinition Height="30" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <Canvas Grid.Row="0">
        <Menu DockPanel.Dock="Top" ItemsSource="{Binding Path=Menu}"/>
        <Label Content="{Binding Path=ConnectionProperty}" Canvas.Right="0" Canvas.Bottom="0"/>
    </Canvas>
 </Grid>
</Window>