[英]WPF Listview binding userControl property
我是WPF
新手。 我有Listview
,并且我想在其中显示更多的usercontrol
。
我使用了ItemTemplate。
这样的Listview:
<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>
我想通过此代码绑定用户控件:
listView1.ItemsSource = DriveInfo.GetDrives()
.Where(item => item.IsReady && item.DriveType == DriveType.Removable)
.ToList();
DriveInfo
类具有名为Name
属性
有人告诉我为什么它不绑定吗?
WPF的主要实现方法是MVVM(模型视图ViewModel),而不是后面的代码。 您需要做的是实现MVVM开发模式。 我是否可以建议您先阅读许多有关MVVM的在线文章之一, 网址为http://msdn.microsoft.com/zh-cn/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");
}
}
到目前为止,我还可以吗? 因此,现在我们有了一个视图模型和一个空字符串值列表。 很棒吗? 下一步是填充字符串“ Drives”列表,因此我们在该类中编写了一个简单的Init方法。
public void Init() {
this.Drives = new ObservableCollection<string>(DriveInfo.GetDrives()
.Where(item => item.IsReady && item.DriveType == DriveType.Removable)
.ToList());
}
让我们暂时不讲代码,现在我们将注意力转移到View(您的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"/>
这样,您的视图模型就可以担心列表的状态和填充,而UI正是按照它的指示进行的。
所以你有它。 这很重要,特别是如果您刚接触WPF时,请先阅读MVVM模式开发,因为一旦启动它就真的很难停止,并且您会想知道之前曾经做过什么。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.