Datagrid 不显示来自 ObservableCollection 的 MVVM 中的数据
Datagrid not displaying data in MVVM from ObservableCollection
我正在使用 MVVM 构建一个基本的 WPF 应用程序。我正在尝试获取有关不同发电厂的数据以显示在 Datagrid 上。该程序构建良好并显示网格线,但没有数据。我见过很多类似的问题并尝试了几件事,但似乎没有任何效果。我想知道这个问题是否只是一件我不知道要寻找的简单事情。
查看:
public class Plant : INotifyPropertyChanged
{
#region Properties
private int plantID;
public int PlantID
{
get { return plantID; }
set
{
plantID = value;
RaisePropertyChanged("PlantID");
}
}
//...etc for all properties//
#endregion
void RaisePropertyChanged(string prop)
{
if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(prop)); }
}
public event PropertyChangedEventHandler PropertyChanged;
}
视图模型:
public class MainViewModel : ViewModelBase, IPlantViewModel
{
private ObservableCollection<Plant> _plants = new ObservableCollection<Plant>();
private ICommand _loadCommand;
public MainViewModel()
{
_plants = GetPlants();
_plants.Add(new Plant (){PlantID=1, Name="Orange Plant", Address="1111 Orange Road", PlantPhone="(314)456 7489",PlantFax="(593)202 6948", Contact="John Smith"});
_plants.Add(new Plant() { PlantID = 2, Name = "Blue Plant", Address = "2222 Blue Lane", PlantPhone = "6368967483", PlantFax = "783279948", Contact = "Jane Doe" });
}
public ObservableCollection<Plant> Plants
{
get { return _plants; }
}
public ObservableCollection<Plant> GetPlants()
{
if (_plants == null || _plants.Count == 0)
_loadCommand.Execute(_plants);
return _plants;
}
}
查看:
<UserControl
x:Class="Directory.MVVM.View.DirectoryView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dg="http://schemas.microsoft.com/wpf/2008/toolkit"
xmlns:local="clr-namespace:Directory.ViewModel"
Height="481" Width="708">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="21*"/>
<ColumnDefinition Width="79*"/>
</Grid.ColumnDefinitions>
<DataGrid
ItemsSource="{Binding Source=Plants}"
Name="PlantGrid"
HorizontalAlignment="Left"
Margin="82,54,0,0"
VerticalAlignment="Top"
Height="147" Width="515"
AutoGenerateColumns="False" Grid.ColumnSpan="2">
<DataGrid.DataContext>
<local:MainViewModel />
</DataGrid.DataContext>
<DataGrid.Columns>
<DataGridTextColumn Header="Plant ID" Width="89" Binding="{Binding Path=PlantID,UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" />
<DataGridTextColumn Header="Name" Width="140" Binding="{Binding Path=Name,UpdateSourceTrigger=PropertyChanged, Mode=TwoWay }" />
<DataGridTextColumn Header="Address" Width="90" Binding="{Binding Path=Address, UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" />
<DataGridTextColumn Header="Phone" Width="90" Binding="{Binding Path=PlantPhone, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" />
<DataGridTextColumn Header="Fax" Width="60" Binding="{Binding Path=PlantFax,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" />
<DataGridCheckBoxColumn Header="Contact" Width="58" Binding="{Binding Path=Contact, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" />
</DataGrid.Columns>
</DataGrid>
视图的代码隐藏(不确定我是否应该在此处添加更多代码):
public partial class DirectoryView : UserControl
public DirectoryView()
{
InitializeComponent();
}
此外,我将此作为参考:
http://wpfgrid.blogspot.com/2014/02/simple-observablecollection-wpf-mvvm.html
尝试在您的数据网格中更改您的项目源绑定,您有源而不是路径。来自
ItemsSource="{Binding Source=Plants}"
到
ItemsSource="{Binding Path=Plants}"
或
ItemsSource="{Binding Plants}"
更改您的绑定将解决您的数据未显示在网格中的问题,至少对于您在 mainviewmodel 的构造函数中添加的 id 为 1 和 2 的两个工厂。您还可以在构造函数中调用 GetPlants,它通过调用命令执行来加载其他植物。我们看不到您是如何将植物添加到 observablecollection 中的。您可能想看看如何将这些植物添加到 getplants 中的 observablecollection。如果注释掉
_plants = GetPlants();
在
MainViewModel
导致您看到两株植物您还对如何在命令执行方法中添加项目有疑问。
如果您像以前一样设置 DataContext,则每次加载新的 UserControl 时,您的数据网格都会获得 MainView 模型的一个新实例。
<DataGrid.DataContext>
<local:MainViewModel />
</DataGrid.DataContext>
所以您必须先将您的项目来源更改为
ItemsSource="{Binding Path=Plants}"
现在您需要检查的是您如何 "fill" 您的 collection。如果你不使用添加、清除和删除来改变你的 collection 那么你必须提高 OnPropertyChanged() 所以 WPF 注意到有变化。
public ObservableCollection<Plant> Plants
{
get
{
return _plants;
}
set
{
_plants = value;
OnPropertyChanged();
}
}
这是我的做法:
Window 构造函数实例化视图模型(这里我将其作为 属性 但实例化也可以在构造函数内部)并将 DataContext 设置为 ViewModel:
public partial class WinFilesTransmitted : Window
{
static FTViewModel w = new FTViewModel();
public WinFilesTransmitted()
{
InitializeComponent();
DataContext = w;
}
}
DataGrid xaml 然后这样做:
<DataGrid AutoGenerateColumns="False" HorizontalAlignment="Stretch" Margin="0,0,0,0" VerticalAlignment="Stretch"
ItemsSource="{Binding DataContext.oFTrn, RelativeSource={RelativeSource AncestorType={x:Type Window}}}">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding UID}" Header="xID" Width="40"/>
<DataGridTextColumn Binding="{Binding TransID, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Header="TransID" Width="40"/>
<DataGridTextColumn Binding="{Binding DocID, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Header="DocID" Width="40"/>
<DataGridTextColumn Binding="{Binding TransmittalName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="325">
所以datagrid的ItemsSource设置为我的observablecollection,列直接绑定属性
我正在使用 MVVM 构建一个基本的 WPF 应用程序。我正在尝试获取有关不同发电厂的数据以显示在 Datagrid 上。该程序构建良好并显示网格线,但没有数据。我见过很多类似的问题并尝试了几件事,但似乎没有任何效果。我想知道这个问题是否只是一件我不知道要寻找的简单事情。
查看:
public class Plant : INotifyPropertyChanged
{
#region Properties
private int plantID;
public int PlantID
{
get { return plantID; }
set
{
plantID = value;
RaisePropertyChanged("PlantID");
}
}
//...etc for all properties//
#endregion
void RaisePropertyChanged(string prop)
{
if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(prop)); }
}
public event PropertyChangedEventHandler PropertyChanged;
}
视图模型:
public class MainViewModel : ViewModelBase, IPlantViewModel
{
private ObservableCollection<Plant> _plants = new ObservableCollection<Plant>();
private ICommand _loadCommand;
public MainViewModel()
{
_plants = GetPlants();
_plants.Add(new Plant (){PlantID=1, Name="Orange Plant", Address="1111 Orange Road", PlantPhone="(314)456 7489",PlantFax="(593)202 6948", Contact="John Smith"});
_plants.Add(new Plant() { PlantID = 2, Name = "Blue Plant", Address = "2222 Blue Lane", PlantPhone = "6368967483", PlantFax = "783279948", Contact = "Jane Doe" });
}
public ObservableCollection<Plant> Plants
{
get { return _plants; }
}
public ObservableCollection<Plant> GetPlants()
{
if (_plants == null || _plants.Count == 0)
_loadCommand.Execute(_plants);
return _plants;
}
}
查看:
<UserControl
x:Class="Directory.MVVM.View.DirectoryView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dg="http://schemas.microsoft.com/wpf/2008/toolkit"
xmlns:local="clr-namespace:Directory.ViewModel"
Height="481" Width="708">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="21*"/>
<ColumnDefinition Width="79*"/>
</Grid.ColumnDefinitions>
<DataGrid
ItemsSource="{Binding Source=Plants}"
Name="PlantGrid"
HorizontalAlignment="Left"
Margin="82,54,0,0"
VerticalAlignment="Top"
Height="147" Width="515"
AutoGenerateColumns="False" Grid.ColumnSpan="2">
<DataGrid.DataContext>
<local:MainViewModel />
</DataGrid.DataContext>
<DataGrid.Columns>
<DataGridTextColumn Header="Plant ID" Width="89" Binding="{Binding Path=PlantID,UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" />
<DataGridTextColumn Header="Name" Width="140" Binding="{Binding Path=Name,UpdateSourceTrigger=PropertyChanged, Mode=TwoWay }" />
<DataGridTextColumn Header="Address" Width="90" Binding="{Binding Path=Address, UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" />
<DataGridTextColumn Header="Phone" Width="90" Binding="{Binding Path=PlantPhone, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" />
<DataGridTextColumn Header="Fax" Width="60" Binding="{Binding Path=PlantFax,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" />
<DataGridCheckBoxColumn Header="Contact" Width="58" Binding="{Binding Path=Contact, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" />
</DataGrid.Columns>
</DataGrid>
视图的代码隐藏(不确定我是否应该在此处添加更多代码):
public partial class DirectoryView : UserControl
public DirectoryView()
{
InitializeComponent();
}
此外,我将此作为参考:
http://wpfgrid.blogspot.com/2014/02/simple-observablecollection-wpf-mvvm.html
尝试在您的数据网格中更改您的项目源绑定,您有源而不是路径。来自
ItemsSource="{Binding Source=Plants}"
到
ItemsSource="{Binding Path=Plants}"
或
ItemsSource="{Binding Plants}"
更改您的绑定将解决您的数据未显示在网格中的问题,至少对于您在 mainviewmodel 的构造函数中添加的 id 为 1 和 2 的两个工厂。您还可以在构造函数中调用 GetPlants,它通过调用命令执行来加载其他植物。我们看不到您是如何将植物添加到 observablecollection 中的。您可能想看看如何将这些植物添加到 getplants 中的 observablecollection。如果注释掉
_plants = GetPlants();
在
MainViewModel
导致您看到两株植物您还对如何在命令执行方法中添加项目有疑问。
如果您像以前一样设置 DataContext,则每次加载新的 UserControl 时,您的数据网格都会获得 MainView 模型的一个新实例。
<DataGrid.DataContext>
<local:MainViewModel />
</DataGrid.DataContext>
所以您必须先将您的项目来源更改为
ItemsSource="{Binding Path=Plants}"
现在您需要检查的是您如何 "fill" 您的 collection。如果你不使用添加、清除和删除来改变你的 collection 那么你必须提高 OnPropertyChanged() 所以 WPF 注意到有变化。
public ObservableCollection<Plant> Plants
{
get
{
return _plants;
}
set
{
_plants = value;
OnPropertyChanged();
}
}
这是我的做法:
Window 构造函数实例化视图模型(这里我将其作为 属性 但实例化也可以在构造函数内部)并将 DataContext 设置为 ViewModel:
public partial class WinFilesTransmitted : Window
{
static FTViewModel w = new FTViewModel();
public WinFilesTransmitted()
{
InitializeComponent();
DataContext = w;
}
}
DataGrid xaml 然后这样做:
<DataGrid AutoGenerateColumns="False" HorizontalAlignment="Stretch" Margin="0,0,0,0" VerticalAlignment="Stretch"
ItemsSource="{Binding DataContext.oFTrn, RelativeSource={RelativeSource AncestorType={x:Type Window}}}">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding UID}" Header="xID" Width="40"/>
<DataGridTextColumn Binding="{Binding TransID, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Header="TransID" Width="40"/>
<DataGridTextColumn Binding="{Binding DocID, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Header="DocID" Width="40"/>
<DataGridTextColumn Binding="{Binding TransmittalName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="325">
所以datagrid的ItemsSource设置为我的observablecollection,列直接绑定属性