我想不出这个办法来拯救我的生命。
我有一个简单的 WPF 表单,我在文本框中输入数据,用户可以单击“插入”并将其保存到数据库中。我还有一个显示所有值的数据网格。
插入新项目后,我无法使用完整的值列表来“刷新”数据网格。我已经用谷歌搜索了好几天,但我就是不知道我缺少哪一行来与 UI 通信以刷新网格视图。
请帮助我,看在上帝的份上,请有人帮助我摆脱这个新手噩梦
这是我的视图模型
public partial class CatView : ObservableObject
{
private List<Category> _Cats = Category.all.Values.ToList();
public List<Category> Cats
{
get { return _Cats; }
set
{
_Cats = value;
OnPropertyChanged("Cats");
}
}
}
WPF 表单 XAML
`<Window x:Class="Recycle4Core.CategoryEdit"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Recycle4Core.ViewModels"
mc:Ignorable="d"
Title="Category Editor" Height="450" Width="800">
<Window.DataContext>
<local:CatView />
</Window.DataContext>
<Grid>
<!--<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="2*"/>
</Grid.RowDefinitions>-->
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel x:Name="InputStack"
Orientation="Vertical"
Grid.IsSharedSizeScope="True">
<Grid x:Name="GridPanelNameInput">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="FirstColumn" />
<ColumnDefinition SharedSizeGroup="SecondColumn" />
</Grid.ColumnDefinitions>
<Label Content="Category Name"
Margin="0,10,0,0" />
<TextBox x:Name="txtINPUT"
Text="{Binding SelectedCategory.name}"
Height="20"
Width="150"
Grid.Column="1" />
</Grid>
<Grid x:Name="ButtonGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="FirstColumn" />
<ColumnDefinition SharedSizeGroup="SecondColumn"/>
<ColumnDefinition SharedSizeGroup="ThirdColumn"/>
</Grid.ColumnDefinitions>
<Button x:Name="btnInsert"
Height="20"
Width="100"
Content="Insert"
Margin="20 10 0 0"
Grid.Column="0"
Click="btnInsert_Click"
/>
<Button x:Name="btnUpdate"
Height="20"
Width="100"
Content="Update"
Margin="20 10 0 0"
Grid.Column="1"/>
<Button x:Name="btnDelete"
Height="20"
Width="100"
Content="Delete"
Margin="20 10 0 0"
Grid.Column="2"/>
</Grid>
<Button x:Name="btnExit"
Height="40"
Width="150"
Content="EXIT"
Margin="0 30 0 0"
HorizontalAlignment="Center"
/>
</StackPanel>
<!--<DataGrid x:Name="grdCategory"
Grid.Column="1"
AutoGenerateColumns="False"
SelectedItem="{Binding Selected}"
>
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding name}" />
</DataGrid.Columns>
</DataGrid>-->
<DataGrid x:Name="grdCategory"
Grid.Column="1"
AutoGenerateColumns="False"
SelectedItem="{Binding SelectedCategory}"
ItemsSource="{Binding Categories}"
>
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding name}" />
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>`
WPF 表单代码
` private void btnInsert_Click(object sender, RoutedEventArgs e)
` {
string newName = txtINPUT.Text.ToString();
Category test = Category.get(newName);
if (test != null)
{
MessageBox.Show("This Category Already Exists, Item was not Saved", "ERROR", MessageBoxButton.OK, MessageBoxImage.Error);
return;
}
if (txtINPUT.Text.ToString() != null )
{
List<Category> categoryData = new List<Category>();
Category cat = new Category(txtINPUT.Text);
categoryData.Add(cat);
Category.add(cat);
Category.Raw cats = new Category.Raw(categoryData);
CategoryDAO.categoriesInsert(cats);
grdCategory.Items.Refresh();
CategoryDAO.loadData();
}
}
``
我尝试使用 ObservableCollection 而不是 List<>。我尝试了 MVVM 工具包中的各种属性。我已经阅读、搜索、阅读、搜索。我就是想不通。我知道这是一些愚蠢的简单的事情,它让我发疯,因为我无法在我的应用程序的实际价值上取得任何进展,因为我在这些废话上旋转
首先,如果你想学习WPF,你不应该将它视为Windows窗体。有很多很好的教程都是从基本概念开始的。 我没有找到将 Categories property 绑定到 DataGrid 作为项目源。您的代码是否缺少某些内容?
但在那之前
1.you ViewModel 类(看起来是一个窗口)应该实现 INotifyPropertyChange 接口。这样它就可以与视图通信。像这样:
public partial class CatView : INotifyPropertyChanged
{
private ObservableCollection<Category> _Cats = Category.all.Values.ToList();
public ObservableCollection<Category> Cats
{
get { return _Cats; }
set
{
_Cats = value;
OnPropertyChanged();
}
}
public ICommand AddCommand { get; set; }
public CatView()
{
AddCommand = new RelayCommand(Add);
}
private void Add(object obj)
{
Cats?.Add(new Category());
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
如你所见
2.以下是RelayCommand实现示例:
public class RelayCommand : ICommand
{
private readonly Action<object> execute;
private readonly Predicate<object> canExecute;
public event EventHandler CanExecuteChanged
{
add
{
CommandManager.RequerySuggested += value;
}
remove
{
CommandManager.RequerySuggested -= value;
}
}
public RelayCommand(Action execute, Predicate<object> canExecute = null)
{
if (execute == null)
{
throw new System.ArgumentNullException("execute");
}
this.execute = delegate
{
execute();
};
this.canExecute = canExecute;
}
public RelayCommand(Action<object> execute, Predicate<object> canExecute = null)
{
this.execute = execute ?? throw new System.ArgumentNullException("execute");
this.canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
if (canExecute != null)
{
return canExecute(parameter);
}
return true;
}
public void Execute(object parameter)
{
execute(parameter);
}
}