2013-05-01 177 views
0

我是WPF。我有Listview,我想在它上面顯示多於usercontrolWPF ListView綁定userControl屬性

我用ItemTemplate。

列表視圖像這樣:

<ListView HorizontalAlignment="Stretch" Margin="0,40,0,0" Name="listView1" VerticalAlignment="Stretch" 
       ItemTemplate="{StaticResource DriveUserControlDataTemplate}" > 
     <ListView.ItemsPanel> 
      <ItemsPanelTemplate> 
       <WrapPanel Width="{Binding (FrameworkElement.ActualWidth), RelativeSource={RelativeSource AncestorType=ScrollContentPresenter}}" 
           ItemWidth="{Binding (ListView.View).ItemWidth, RelativeSource={RelativeSource AncestorType=ListView}}" 
           MinWidth="{Binding ItemWidth, RelativeSource={RelativeSource Self}}" 
           ItemHeight="{Binding (ListView.View).ItemHeight, RelativeSource={RelativeSource AncestorType=ListView}}" /> 
      </ItemsPanelTemplate> 
     </ListView.ItemsPanel> 
    </ListView> 


    <DataTemplate x:Key="DriveUserControlDataTemplate" > 
     <StackPanel Margin="10"> 
      <c:DriveUserControl Drive="{Binding Name}" EventAdd="DriveUserControlAdd_Click"> 
      </c:DriveUserControl > 
     </StackPanel> 
    </DataTemplate> 

,我想通過這個代碼綁定用戶控件:DriveInfo

listView1.ItemsSource = DriveInfo.GetDrives() 
       .Where(item => item.IsReady && item.DriveType == DriveType.Removable) 
       .ToList(); 

級轎車屬性命名Name

任何一個可以告訴我,爲什麼它沒有約束力?

回答

0

WPF實現的主要方法是MVVM(Model View ViewModel),而不是代碼隱藏。你需要做的是實現MVVM開發模式。我可以建議你先閱讀關於MVVM的許多在線文章之一,http://msdn.microsoft.com/en-us/magazine/dd419663.aspx

但是,不要只指着你一個鏈接,我會盡力嘗試回答你的問題,盡我所能。

創建一個類並將其稱爲MainWindowViewModel並實現INotifyPropertyChanged接口。一旦你完成了這個實現PropertyChanged事件。此時,我喜歡欺騙自己,並寫下自己的幫手,以便在我的房產改變時爲我舉辦這個活動。

public class MainWindowViewModel : INotifyPropertyChanged { 
    public event PropertyChangedEventHandler PropertyChanged; 

    private void raisePropertyChanged(string propertyName) { 
    if (PropertyChanged != null) PropretyChanged(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 

所以在這一點上,你應該有一些東西,如上圖所示。這是ViewModel。

下一步是創建您想要公開給用戶界面的視圖。在你的情況下,你想列出你的計算機上可用的驅動器。所以我們需要創建一個字符串值的ObservableCollection,如下所示。

private ObservableCollection<string> _drives = new ObservableCollection<string>(); 
public ObservableCollection<string> Drives { 
    get { return _drives; } 
    set { 
    _drives = value; 
    this.raisePropertyChanged("Drives"); 
    } 
} 

好的,我到目前爲止?所以現在我們有一個視圖模型和一個空的字符串值列表。真棒HUH?下一步是填充字符串「Drives」的列表,所以我們在類中編寫一個簡單的Init方法。

public void Init() { 
    this.Drives = new ObservableCollection<string>(DriveInfo.GetDrives() 
       .Where(item => item.IsReady && item.DriveType == DriveType.Removable) 
       .ToList()); 
} 

讓我們暫時留下代碼,現在我們將注意力轉向視圖(您的UI)。在你的UI中,你需要定義你的ViewModel類所在的命名空間。這是放入窗口中xaml的第一個元素。

xmlns:vms="clr-namespace:applicationNameSpace;assembly=applicationAssemblyName" 

不要忘記用applicationNameSpace和applicationAssemblyName替換正確的值。

接下來我們在窗口的資源中聲明ViewModel類。

<Window.Resources> 
    <vms:MainWindowViewModel x:Key="mainWindowVms"/> 
</Window.Resources> 

最後但並非最不重要創建你的窗口,並在後面的代碼中的Loaded事件,是的,我說後面的代碼,把下面的代碼。

MainWindowViewModel mainWindowVms = Resources["mainWindowVms"] as MainWindowViewModel; 
mainWindowVms.Init(); 

所以這隻剩下最後一件事了,這是回答你關於「爲什麼它沒有綁定?」的問題。那麼因爲ItemsSource是需要通過ViewModel的屬性綁定的屬性。換句話說,它使用INotifyPropertyChanged接口來通知UI線程已對其綁定的對象進行了更改。在代碼背後的綁定類型擊敗了WPF的目的。因此,爲了獲得綁定,您只需在xaml中指定綁定即可。

<ListView ItemsSource="{Binding Source={StaticResource mainWindowVms}, Path=Drives"/> 

您對列表的狀態,人口和您的用戶界面視圖模型擔心這樣只是做什麼它說。

所以你有它。這很重要,特別是如果您是WPF的新手,並且閱讀了MVVM模式開發方面的內容,因爲一旦啓動它,真的很難停下來,並且您會想知道您之前做過什麼。

+0

非常感謝 – 2013-05-01 20:47:52

+0

沒問題。我希望答案適合。如果這可以解決您的問題,請標記爲已解決。 – sepai 2013-05-02 04:08:44