2013-01-18 130 views
2

我的客戶端應用程序可以連接到不同的服務器應用程序,因此我想將連接信息動態添加到窗口標題中。標題綁定到ViewModel的一個屬性,它的get在啓動應用程序之後被調用,但它不再被更新,而窗口中的其他控件仍然正常工作。WPF-MVVM綁定屬性窗口標題

這裏是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> 

Title勢必AppTitle,而Label勢必ConnectionProperty,這是工作的罰款。在XAML.cs我設置ViewModelViewDataContext

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

MainWindowViewModel的構造:

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

啓動應用程序後,將Title正確顯示。然後我連接到服務器:

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

在此之後,Title保持不變,而Label得到ConnectionProperty值。

下面是兩個屬性的定義,這是幾乎相同的:

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

任何想法,爲什麼不更新Title,但Label

+3

你有'Windows1ViewModel'在資源中,但是從代碼爲窗口創建一個新的DataContext。我們沒有這樣的ViewModel的兩個實例嗎? – Aphelion

+0

我同意Aphelion,我認爲你創建兩次的問題(在代碼和XAML中) – chameleon86

+0

我同意你的意見。你有一個viewmodel爲你的窗口和一個專門爲你的網格。標題綁定到window-viewmodel,標籤綁定到grid-viewmodel。你只更新第二個(菜單也使用這個),所以標題不會改變。解決方案是刪除網格的DataContext,因爲它繼承了窗口的DataContext。 – webber2k6

回答

1

您在Grid.Resources中有Windows1ViewModel,但是您從代碼爲窗口創建了一個新的DataContext。你有這樣的ViewModel的兩個實例。

0

如前所述對這個問題的樓主:


我註釋掉我需要刪除線,以使其正常工作:

<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>