2009-09-28 43 views
2

我想在這裏做一些非常基本的事情,我不希望給我這麼多問題。我在我的主窗口類上有一個名爲ItemList的公共屬性,它的類型爲List<string>。我在程序的整個生命週期中都添加到了這個列表中,並且希望我的表單上的ListBox控件在將新項添加到ItemList屬性時自動更新。WPF - 將列表框綁定到列表<string> - 我做錯了什麼?

到目前爲止,我有以下XAML:

<Window x:Class="ElserBackupGUI.Main" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="Backup Profile Editor [New Profile]" Height="480" Width="640"> 
    <DockPanel> 
     <Menu DockPanel.Dock="Top"> 
      <MenuItem Header="File"> 
       <MenuItem Header="Open"/> 
      </MenuItem> 
     </Menu> 
     <StackPanel Orientation="Vertical" DockPanel.Dock="Top" Margin="10 10 10 3"> 
      <TextBlock>Items to backup:</TextBlock> 
     </StackPanel> 
     <DockPanel DockPanel.Dock="Bottom" Margin="10 0 10 10"> 
      <StackPanel Orientation="Horizontal"> 
       <Button Name="AddDirectoryButton" Height="22.725" Width="120" Margin="0 0 6 0" Click="AddDirectoryButton_Click">Add Directory...</Button> 
       <Button Name="AddFileButton" Height="22.725" Width="90" Margin="0 0 6 0" Click="AddFileButton_Click">Add File...</Button> 
       <Button Name="RemoveDirectoriesButton" Height="22.725" Width="75.447" Margin="0 0 6 0">Remove</Button> 
      </StackPanel> 
     </DockPanel> 
     <ListBox Name="SelectedItems" Margin="10 0 10 10" ItemsSource="{Binding Path=ItemList}"/> 
    </DockPanel> 
</Window> 

相關的代碼隱藏代碼如下所示:

public partial class Main : Window 
{ 
    private string _lastFolder = string.Empty; 
    private ObservableCollection<string> _itemList = new ObservableCollection<string>(); 

    public ObservableCollection<string> ItemList { 
     get { return _itemList ?? (_itemList = new ObservableCollection<string>()); } 
     set { _itemList = value; } 
    } 

    public Main() 
    { 
     InitializeComponent(); 
     ItemList.Add("test item"); 
     DataContext = this; 
    } 

    private void AddDirectoryButton_Click(object sender, RoutedEventArgs e) 
    { 
     FolderBrowserDialog dialog = new FolderBrowserDialog(); 
     if (!string.IsNullOrEmpty(_lastFolder)) 
      dialog.SelectedPath = _lastFolder; 

     if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) 
     { 
      _lastFolder = dialog.SelectedPath; 
      ItemList.Add(dialog.SelectedPath); 
     } 
    } 

    private void AddFileButton_Click(object sender, RoutedEventArgs e) 
    { 
     OpenFileDialog dialog = new OpenFileDialog(); 
     if (!string.IsNullOrEmpty(_lastFolder)) 
      dialog.InitialDirectory = _lastFolder; 

     if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) 
     { 
      _lastFolder = System.IO.Path.GetDirectoryName(dialog.FileName); 
      SelectedItems.ItemsSource = null; 
      ItemList.Add(dialog.FileName); 
     } 
    } 
} 

我是比較新的WPF和大多數的教程似乎過於複雜的這樣一個簡單的問題。我似乎無法在這裏找到任何地方 - 我錯過了什麼?

回答

8

您應該使用BindingList<T>ObservableCollection<T>而不是List<T>

問題是,按照你想要的方式進行綁定,需要執行INotifyCollectionChangedIBindingListList<T>不支持這一點。


編輯:

審查更改後,仍然有一個問題。

在AddFileButton_Click事件處理程序,刪除以下行:

SelectedItems.ItemsSource = null; 

被明確刪除你的綁定,並導致列表框中清除。如果你刪除它,你的代碼應該按原樣工作。

不過,我建議改變您的收藏定義和構造的東西更像:

// No need for the null checking every time, or public setter. They just cause issues 
    public ObservableCollection<string> ItemList 
    { 
     get; 
     private set; 
    } 

    // Add construction here, now that we're using an auto-prop 
    public Main() 
    { 
     this.ItemList = new ObservableCollection<string>(); 
     InitializeComponent(); 
     ItemList.Add("test item"); 
     DataContext = this; 
    } 
+1

使用ObservableCollection而不是BindingList,因爲它專門爲WPF綁定場景而設計 – 2009-09-28 19:24:44

+0

我提到了兩者,並相信它們都提供了優勢。我通常會同意並推薦ObservableCollection,但如果您的集合也可能被非WPF應用程序使用,那麼BindingList可以提供優勢。 – 2009-09-28 19:28:32

+0

我嘗試將列表更改爲ObservableCollection 並且沒有任何更改。它運行良好,但添加項目到收藏沒有更新列表框控件 – Chris 2009-09-28 19:30:31

1

我不喜歡這樣的吸氣......個人。看起來很顯眼。

get { return _itemList ?? (_itemList = new ObservableCollection<string>()); } 

您已經在聲明中初始化_itemList。如果你需要雙倍的時間來感受安全,那就在構造函數中完成。

+0

我同意 - 我在最新的編輯中也提到過。這不會導致他的問題,但 - 這只是沒有任何幫助。 – 2009-09-28 20:22:32

+0

是的,額外的代碼是我在聲明中初始化列表之前。我已經刪除了冗餘代碼。 – Chris 2009-09-28 20:34:40