2016-01-03 65 views
0

我正在努力解決更新問題。我有一個綁定到一個觀察的集合列表框選項卡控制MVVM列表框中的選項卡控件沒有更新

ListBox HorizontalAlignment="Center" Height="450" VerticalAlignment="Top" Width="250" 
    x:Name="LbxMenu" Background="{x:Null}" BorderBrush="{x:Null}" 
    ItemsSource="{Binding TestListsNames}" FontFamily="Segoe UI Semilight" FontSize="18"/> 

視圖模型:

private ObservableCollection<string> _testListsName; 

    public ObservableCollection<string> TestListsNames 
    { 
     get { return _testListsName; } 
     set{ _testListsName = value; } 
    } 

插入實體數據庫之後有一個調用TestListInitialize方法在我的ViewModel應該刷新收集和事件它可以在調試器中看到它。但是listbox不刷新,我必須重新啓動應用程序才能看到更改。 它在單獨的窗口中工作的很好,但是當我改變UI到標籤控件時它沒有。

更新功能:

private void TestListNamesInitialize() 
    { 
     TestListsNames = db.GetTestListNamesFromDatabase(); 
     if (TestListsNames.Count != 0) CanLoad = true;   

    } 

初始窗口:

<Controls:MetroWindow 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    x:Class="Test.View.InitialWindow" 
    xmlns:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro" 
    xmlns:tabdata="clr-namespace:Test.View.TabItems" 

    Title="Testownik" Height="600" Width="900" ShowTitleBar="True" ResizeMode="NoResize" Icon="../GraphicResources/Icon.ico"> 


<Controls:MetroWindow.RightWindowCommands> 
    <Controls:WindowCommands> 
     <Button Content="settings" /> 
     <Button> 
      <StackPanel Orientation="Horizontal"> 
       <TextBlock Margin="4 0 0 0" 
       VerticalAlignment="Center" 
       Text="about" /> 
      </StackPanel> 
     </Button> 
    </Controls:WindowCommands> 
</Controls:MetroWindow.RightWindowCommands> 
<Controls:MetroAnimatedTabControl x:Name ="MainTabControl"> 
    <TabItem Header="Learn" Width="280"> 
     <tabdata:LearnTabItem/> 
    </TabItem> 
    <TabItem Header="Database" Width="280"> 
     <tabdata:DatabaseTabItem/> 
    </TabItem> 
    <TabItem Header="Statistics" Width="299"> 
     <tabdata:StatisticsTabItem/> 
    </TabItem> 
</Controls:MetroAnimatedTabControl> 

後面的代碼:

public partial class InitialWindow : MetroWindow 
{ 
    InitialWindowViewModel viewModel=new InitialWindowViewModel(); 
    public InitialWindow() 
    { 
     InitializeComponent(); 
     DataContext = viewModel; 
    } 
} 

}

DatabaseTabItem:

<UserControl x:Class="Test.View.TabItems.DatabaseTabItem" 
     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:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro" 
     xmlns:tabData="clr-namespace:Test.View.TabItems" 
     Height="500" Width="900" Background="White" BorderBrush="Transparent"> 
<UserControl.Resources> 


</UserControl.Resources> 
<Grid> 

    <Controls:MetroAnimatedTabControl x:Name ="DatabaseTabControl" Grid.Column="0" TabStripPlacement="Left" > 
     <TabItem Header="Choose" Width="250" > 
      <tabData:ChooseFromDbTabItem/> 
     </TabItem> 
     <TabItem Header="Add" Width="250"> 
      <tabData:AddToDbTabItem/> 
     </TabItem> 
     <TabItem Header="Remove" Width="250"> 
      <tabData:DeleteFromDbTabItem/> 
     </TabItem> 
    </Controls:MetroAnimatedTabControl> 
</Grid> 

代碼後面:

DatabaseViewModel vm = new DatabaseViewModel(); 
    public DatabaseTabItem() 
    { 
     InitializeComponent(); 
     DataContext = vm; 
    } 

} 

ChooseFromDbTabItem:

<UserControl x:Class="Test.View.TabItems.ChooseFromDbTabItem" 
     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" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:local="clr-namespace:Test.View.TabItems" 
     xmlns:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro" 

     mc:Ignorable="d" 
     d:DesignHeight="500" d:DesignWidth="650" Background="White" BorderBrush="Transparent"> 

<Grid> 
    <ListBox HorizontalAlignment="Center" Height="450" VerticalAlignment="Top" Width="250" 
    x:Name="LbxMenu" Background="{x:Null}" BorderBrush="{x:Null}" 
    ItemsSource="{Binding TestListsNames}" FontFamily="Segoe UI Semilight" FontSize="18"/> 
</Grid> 

後面的代碼:

public partial class ChooseFromDbTabItem : UserControl 
{ 
    public ChooseFromDbTabItem() 
    { 
     InitializeComponent(); 
    } 
} 
+1

如何更新列表?你能提供這些代碼嗎?即TestListInitialize方法。我懷疑你正在使用屬性setter,它不會引發任何PropertyChanged事件。 – lenkan

+0

數據庫: '公共無效ImportToDatabase(串測試名) { _testName =測試名; DocumentProcessor processor = new DocumentProcessor(); processor.ProcessDocFile(); OnDatabaseUpdated(new EventArgs()); }' 視圖模型: 構造器: '公共DatabaseViewModel() { 分貝=新DatabaseOperations(); \t \t ..... \t db.DatabaseUpdated + =(發件人,參數)=> TestListNamesInitialize(); \t} ' – derb

+0

請更新代碼你的問題。在評論部分很難閱讀代碼。 – lenkan

回答

1

你必須上升PropertyChanged事件爲你改變的原因您整個集合而不是單個項目(如果你改變了單一的通過Observable更新的項目)。

private ObservableCollection<string> _testListsName; 
    public ObservableCollection<string> TestListsNames 
    { 
     get { return _testListsName; } 
     set 
     { 
      if (_testListsName != value) 
      { 
       _testListsName = value; 
       NotifyPropertyChanged("TestListsNames"); 
      } 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
    private void NotifyPropertyChanged(string property) 
    { 
     if (PropertyChanged != null) 
      PropertyChanged(this, new PropertyChangedEventArgs(property)); 
    } 
+1

它的工作原理,謝謝。我認爲ObservableCollection會自動升高它 – derb

+0

如果列表中的某些內容發生更改(添加,刪除,替換...),則ObservableCollection上升,但如果我們更改列表(新建),則需要更改屬性。 –

1

當使用屬性設置器替換列表時,不會引發PropertyChanged事件。一般來說,儘量使採集屬性只讀,以減少這類錯誤的風險。相反,清除列表並重新填充它。這將確保視圖被通知任何更改。

public class ViewModel 
{ 
    private readonly ObservableCollection<string> _testListsName; 

    public ObservableCollection<string> TestListsNames 
    { 
     get { return _testListsName; } 
    } 

    private void TestListNamesInitialize() 
    { 
     _testListsName.Clear(); 
     foreach(string name in db.GetTestListNamesFromDatabase()) 
     { 
      _testListsName.Add(name); 
     } 

     if (_testListsNames.Count != 0) CanLoad = true; 
    } 
} 

但是,請注意,這會使用.Add()調用引發每個項目上的更改事件。看到這裏:Can I somehow temporarily disable WPF data binding changes?

編輯:從您更新的代碼。也可以看出,您不在ChooseFromDbTabItem上設置DataContext。您需要DataContext屬性綁定到公開集合視圖模型:

<TabItem Header="Choose" Width="250" > 
    <tabData:ChooseFromDbTabItem DataContext="{Binding}" /> 
</TabItem> 
+0

它仍然無法正常工作 – derb

+0

@derp - 你在哪裏初始化列表中的第一次? – lenkan

+0

在視圖模型 – derb

相關問題