我有一个视图模型,它继承自 ParentModel 类型的可观察集合类。该视图模型绑定到用户控件中的一个按钮,单击该按钮时,它将在主窗口的 datagrid 控件中添加一个新条目。该数据网格也绑定到视图模型,但是当我尝试添加新的父级时,数据网格中没有显示新的条目/行。我的问题是如何将视图模型的同一实例从用户控件中的按钮引用到 datagrid 控件?
下面是一个示例代码
查看模型:
public class ParentViewModel : ObservableCollection<ParentModel>
{
public void AddParent(ParentModel parentModel)
{
Add(parentModel);
}
}
用户控件 XAML 中的按钮:
<Button Grid.Row="9" Grid.Column="1" x:Name="btnAddParent" HorizontalAlignment="Right" Content="Add Parent" Width="98" Background="{x:Null}" Height="25" VerticalAlignment="Top" FontSize="12" FontWeight="Bold" Command="{Binding AddParentCommand, Source={StaticResource parentViewModel}}" CommandParameter="{Binding}" />
来自主窗口 XAML 的数据网格:
<DataGrid x:Name="dgvParent" Grid.Row="1" HorizontalAlignment="Stretch" Height="Auto" VerticalAlignment="Stretch" Width="Auto" SelectionMode="Single" BorderThickness="2" Style="{StaticResource AzureDataGrid}" AutoGenerateColumns="False" AlternatingRowBackground="LightBlue" DataContext="{Binding Source={StaticResource parentViewModel}}" ItemsSource="{Binding}" CanUserAddRows="False">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding PId}" FontWeight="Bold" Header="Id" />
<DataGridTextColumn Binding="{Binding PLastName}" FontWeight="Bold" Header="Last Name" />
<DataGridTextColumn Binding="{Binding PFirstName}" FontWeight="Bold" Header="First Name" />
<DataGridTextColumn Binding="{Binding PMiddleName}" FontWeight="Bold" Header="Middle Name" />
<DataGridTextColumn Binding="{Binding PAddress}" FontWeight="Bold" Header="Address" />
<DataGridTextColumn Binding="{Binding PContactNo}" FontWeight="Bold" Header="Contact Number" />
<DataGridTextColumn Binding="{Binding PEmail}" FontWeight="Bold" Header="Email" />
<DataGridTextColumn Binding="{Binding PCreatedOn}" FontWeight="Bold" Header="Created On" />
<DataGridTextColumn Binding="{Binding PUpdatedAt}" FontWeight="Bold" Header="Updated At" />
</DataGrid.Columns>
</DataGrid>
编辑:
在我的主窗口中,还有另一个绑定到网格的视图模型,该视图模型用于在单击按钮时使用户控件可见。
主视图模型:
public class MainViewModel : INotifyPropertyChanged
{
#region Constructors
public MainViewModel()
{
_showUserControlCommand = new ShowUserControlCommand(ShowUserControl, IsExecutable);
}
#endregion
#region Events
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
#region Methods
public bool IsExecutable(object context)
{
return true;
}
#endregion
#region Commands and Properties
private Visibility _visibility = Visibility.Collapsed;
public Visibility ChangeControlVisibility
{
get { return _visibility; }
set { _visibility = value; OnPropertyChanged("ChangeControlVisibility"); }
}
public void ShowUserControl(object context)
{
if (ChangeControlVisibility == Visibility.Collapsed)
{
ChangeControlVisibility = Visibility.Visible;
}
else
{
ChangeControlVisibility = Visibility.Collapsed;
}
}
private ICommand _showUserControlCommand;
public ICommand ButtonClickCommand
{
get { return _showUserControlCommand; }
set { _showUserControlCommand = value; }
}
#endregion
主窗口 XAML:
<Controls:MetroWindow x:Class="RegistrationApp.Views.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
xmlns:m="clr-namespace:RegistrationApp.Models"
xmlns:vm="clr-namespace:RegistrationApp.ViewModels"
xmlns:vw="clr-namespace:RegistrationApp.Views"
xmlns:cl="clr-namespace:RegistrationApp.Classes"
xmlns:local="clr-namespace:RegistrationApp"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:EntityModels="clr-namespace:RegistrationApp.EntityModels"
mc:Ignorable="d"
Title="MainWindow"
Height="750"
Width="600"
MinHeight="600"
MinWidth="750">
<Controls:MetroWindow.Resources>
<m:ParentModel x:Key="parent" />
<vm:ParentViewModel x:Key="parentViewModel" />
<vm:MainViewModel x:Key="mainViewModel" />
<vw:AddParentUserControl x:Key="addParentUserControl" />
</Controls:MetroWindow.Resources>
<Grid DataContext="{StaticResource mainViewModel}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20px" />
<ColumnDefinition />
<ColumnDefinition Width="20px" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="20px" />
<RowDefinition Height="Auto" />
<RowDefinition />
<RowDefinition Height="20px" />
</Grid.RowDefinitions>
<Grid Grid.Column="1" Grid.Row="1" Height="Auto" Width="Auto">
<Grid.ColumnDefinitions>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Source="/Images/Mobiliar.png" MaxHeight="300" Width="Auto" HorizontalAlignment="Stretch" Stretch="Fill" />
</Grid>
<Controls:MetroAnimatedTabControl Grid.Row="2" Grid.Column="1" Controls:TabControlHelper.IsUnderlined="True" Controls:TabControlHelper.Transition="Left" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="Auto" Height="Auto" FontWeight="Bold" FontSize="14">
<TabItem Header="Parent" Controls:TabControlHelper.Transition="Normal" Margin="0" HorizontalAlignment="Left" Width="110">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal" Height="Auto" Width="Auto" VerticalAlignment="Top" Margin="0,0,0,4">
<Button HorizontalAlignment="Stretch" Height="24" Width="Auto" Margin="20,10,0,0" Command="{Binding ButtonClickCommand}" >
<StackPanel Orientation="Horizontal">
<Image MinHeight="10" MinWidth="10" Source="/Images/add_icon.png" Stretch="UniformToFill" Margin="0,0,2,0" />
<TextBlock Text="Add" FontSize="12" />
</StackPanel>
</Button>
<Button HorizontalAlignment="Stretch" Height="24" Width="Auto" Margin="10,10,0,0">
<StackPanel Orientation="Horizontal">
<Image MinHeight="10" MinWidth="10" Source="/Images/delete_icon.png" Stretch="UniformToFill" Margin="0,0,2,0" />
<TextBlock Text="Delete" FontSize="12" />
</StackPanel>
</Button>
<Button HorizontalAlignment="Stretch" Height="24" Width="Auto" Margin="10,10,0,0">
<StackPanel Orientation="Horizontal">
<Image MinHeight="10" MinWidth="10" Source="/Images/edit_icon.png" Stretch="UniformToFill" Margin="0,0,2,0" />
<TextBlock Text="Edit" FontSize="12" />
</StackPanel>
</Button>
</StackPanel>
<DataGrid x:Name="dgvParent" Grid.Row="1" HorizontalAlignment="Stretch" Height="Auto" VerticalAlignment="Stretch" Width="Auto" SelectionMode="Single" BorderThickness="2" Style="{StaticResource AzureDataGrid}" AutoGenerateColumns="False" AlternatingRowBackground="LightBlue" DataContext="{Binding Source={StaticResource parentViewModel}}" ItemsSource="{Binding}" CanUserAddRows="False">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding PId}" FontWeight="Bold" Header="Id" />
<DataGridTextColumn Binding="{Binding PLastName}" FontWeight="Bold" Header="Last Name" />
<DataGridTextColumn Binding="{Binding PFirstName}" FontWeight="Bold" Header="First Name" />
<DataGridTextColumn Binding="{Binding PMiddleName}" FontWeight="Bold" Header="Middle Name" />
<DataGridTextColumn Binding="{Binding PAddress}" FontWeight="Bold" Header="Address" />
<DataGridTextColumn Binding="{Binding PContactNo}" FontWeight="Bold" Header="Contact Number" />
<DataGridTextColumn Binding="{Binding PEmail}" FontWeight="Bold" Header="Email" />
<DataGridTextColumn Binding="{Binding PCreatedOn}" FontWeight="Bold" Header="Created On" />
<DataGridTextColumn Binding="{Binding PUpdatedAt}" FontWeight="Bold" Header="Updated At" />
</DataGrid.Columns>
</DataGrid>
</Grid>
我的建议是不要使用ObservableCollection
的DataContext。
WPF Window
引用ViewModel
实例。在该视图模型中,放置一个ObservableCollection
属性
public class MyViewModel
{
private ObservableCollection<ParentModel> _myItems = new ObservableCollection<ParentModel>();
public ObservableCollection<ParentModel> MyItems
{
get { return _myItems; }
}
public void AddParent(ParentModel parentModel)
{
this.MyItems.Add(parentModel);
}
}
然后将 Window DataContext 设置为 MyViewModel
的实例。尽管不是最佳实践,但您可以在构造函数的窗口后面的代码中设置它
/* window constructor */
public MyWindow()
{
this.DataContext = new MyViewModel();
}
最后在你的 XAML 中
<DataGrid ... ItemsSource="{Binding MyItems}">
无需在数据网格中设置 DataContext