我是wpf的新手,我目前正在尝试使用网格并添加减法,将元素删除到最终绑定到网格的数据库表。
因此从网格中选择,更新可观察的集合,刷新。
我无法理解如何使用可观察集合的更改通知。
这是我的代码
绑定到网格的类
public class students
{
ObservableCollection<GetStudents_Result> stdb = new ObservableCollection<GetStudents_Result>();
//public event NotifyCollectionChangedEventHandler CollectionChanged;
public students()
{
AbcdEntities abcdEnt=new AbcdEntities();
List<GetStudents_Result> studentColl = abcdEnt.GetStudents().ToList();
foreach (var item in studentColl)
{
stdb.Add(item);
}
}
//public void onCollectionChange(object sender,NotifyCollectionChangedEventHandler e)
//{
//}
public ObservableCollection<GetStudents_Result> std {get {return stdb;}}
}
我的xaml。
<Canvas>
<TextBox Height="23" Canvas.Top="5" Canvas.Left="10" HorizontalAlignment="Left" Margin="10,10,0,0" Name="textBox1" VerticalAlignment="Top" Width="120" />
<TextBox Height="23" Canvas.Top="30" Canvas.Left="10" HorizontalAlignment="Left" Margin="10,10,0,0" Name="textBox2" VerticalAlignment="Top" Width="120" />
<Button Canvas.Left="90" Canvas.Top="65" Content="Remove" Click="button2_Click" Height="23" Name="button2" Width="75" />
<Button Canvas.Left="10" Canvas.Top="65" Content="Save" Height="23" Name="button1" Width="75" Click="button1_Click" />
<ListView Name="listviewStudents" Canvas.Top="100" ItemsSource="{Binding std}" SelectionChanged="ListView_SelectionChanged">
<ListView.View>
<GridView>
<GridViewColumn Header="fname" DisplayMemberBinding="{Binding Path=fname}"></GridViewColumn>
<GridViewColumn Header="lname" DisplayMemberBinding="{Binding Path=lname}"></GridViewColumn>
<GridViewColumn DisplayMemberBinding="{Binding Path=address}"></GridViewColumn>
<GridViewColumn DisplayMemberBinding="{Binding Path=phno}"></GridViewColumn>
<GridViewColumn DisplayMemberBinding="{Binding Path=radio}"></GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</Canvas>
我的代码
public MainWindow()
{
InitializeComponent();
students std = new students();
this.DataContext = std;
}
private void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
GetStudents_Result selectedItem = listviewStudents.SelectedItem as GetStudents_Result;
textBox1.Text = selectedItem.fname;
textBox2.Text = selectedItem.lname;
}
private void button1_Click(object sender, RoutedEventArgs e)
{
GetStudents_Result selecteditem = listviewStudents.SelectedItem as GetStudents_Result;
selecteditem.fname = textBox1.Text;
selecteditem.lname = textBox2.Text;
listviewStudents.Items.Refresh();
}
private void button2_Click(object sender, RoutedEventArgs e)
{
listviewStudents.Items.Remove(listviewStudents.SelectedItem);
listviewStudents.Items.Refresh();
}
}
}
请原谅任何愚蠢的错误..答案 0 :(得分:2)
这里存在一些问题,您不必触及后面代码中的UI
控件,您应该使用数据绑定。
以下是基于帖子的模型绑定的工作示例。
public partial class MainWindow : Window, INotifyPropertyChanged
{
public MainWindow()
{
InitializeComponent();
// set the DataContext to the code in this window
this.DataContext = this;
// create youe Student model
StudentModel = new students();
}
// Create a public property of your student Model
private students _studentModel;
public students StudentModel
{
get { return _studentModel; }
set { _studentModel = value; NotifyPropertyChanged("StudentModel"); }
}
// create a public property to use as the selected item from your models "std" collection
private GetStudents_Result _selectedResult;
public GetStudents_Result SelectedResult
{
get { return _selectedResult; }
set { _selectedResult = value; NotifyPropertyChanged("SelectedResult"); }
}
private void button2_Click(object sender, RoutedEventArgs e)
{
// if you want to remove an item you just have to remove it from
// the model, the INotifyPropertyChanged interface will notify the UI
// to update, no need to call Refresh, same works for Add etc
StudentModel.std.Remove(SelectedResult);
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string property)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
}
现在在xaml
我们可以将ListView
绑定到您的StudentModel
集合和SelectedResult
<ListView ItemsSource="{Binding StudentModel.std}" SelectedItem="{Binding SelectedResult}" >
对于TextBoxes
,您可以绑定到SelectedResult
,以便为您更新详细信息
注意:在此示例中,它会在文本更改时更新SelectedResult,您可以根据需要更改它。
<TextBox Text="{Binding SelectedResult.Fname, UpdateSourceTrigger=PropertyChanged}" />
<TextBox Text="{Binding SelectedResult.Lname, UpdateSourceTrigger=PropertyChanged}" />
现在,当您从ListView
中选择一个项目时,将会填充这些TextBoxes
,并且当这些项目发生更改时,SelectedResult
项目将会更改。
现在,要在ListView
中添加和删除项目,您只需在StudentModel
集合(StudentModel.std)中添加和删除。
private void button2_Click(object sender, RoutedEventArgs e)
{
StudentModel.std.Remove(SelectedResult);
}
注意:此事件处理程序应该是ICommand
绑定,但我会让您搜索:)
这是一个完整的示例,希望有助于解释WPF MVVM
代码:
public partial class MainWindow : Window, INotifyPropertyChanged
{
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
StudentModel = new students();
}
private students _studentModel;
public students StudentModel
{
get { return _studentModel; }
set { _studentModel = value; NotifyPropertyChanged("StudentModel"); }
}
private GetStudents_Result _selectedResult;
public GetStudents_Result SelectedResult
{
get { return _selectedResult; }
set { _selectedResult = value; NotifyPropertyChanged("SelectedResult"); }
}
private void button2_Click(object sender, RoutedEventArgs e)
{
StudentModel.std.Remove(SelectedResult);
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string property)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
}
public class students
{
public students()
{
std = new ObservableCollection<GetStudents_Result>();
for (int i = 0; i < 100; i++)
{
std.Add(new GetStudents_Result { Fname = "FirstName" + i, Lname = "LasrName" + i });
}
}
public ObservableCollection<GetStudents_Result> std { get; set; }
}
public class GetStudents_Result : INotifyPropertyChanged
{
private string _fname;
private string _lname;
public string Fname
{
get { return _fname; }
set { _fname = value; NotifyPropertyChanged("Fname"); }
}
public string Lname
{
get { return _lname; }
set { _lname = value; NotifyPropertyChanged("Lname"); }
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string property)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
}
的Xaml:
<Canvas>
<TextBox Text="{Binding SelectedResult.Fname, UpdateSourceTrigger=PropertyChanged}" />
<TextBox Text="{Binding SelectedResult.Lname, UpdateSourceTrigger=PropertyChanged}" />
<Button Canvas.Left="90" Canvas.Top="65" Content="Remove" Click="button2_Click" Height="23" Name="button2" Width="75" />
<Button Canvas.Left="10" Canvas.Top="65" Content="Save" Height="23" Name="button1" Width="75" />
<ListView Name="listviewStudents" Canvas.Top="100" ItemsSource="{Binding StudentModel.std}" SelectedItem="{Binding SelectedResult}" >
<ListView.View>
<GridView>
<GridViewColumn Header="fname" DisplayMemberBinding="{Binding Path=Fname}"></GridViewColumn>
<GridViewColumn Header="lname" DisplayMemberBinding="{Binding Path=Lname}"></GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</Canvas>
我希望此信息有助于:)
答案 1 :(得分:1)
首先,如果我做得很差,我会道歉。这是我的第一次尝试。
所以看起来你有正确的想法,你所拥有的大部分内容都会奏效。但看起来您可能忘记实施INotifyPropertyChanged
。你可能只考虑使用类似List<GetStudent_Result>
的东西,比ObservableCollection少得多,因为你将自己实现NotifyPropertyChanged。
public class students : INotifyPropertyChanged
{
#region PropertyChanged EventHandler
public event PropertyChangedEventHandler PropertyChanged;
void NotifyPropertyChanged(String Property)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(Property));
}
#endregion
private List<GetStudents_Result> stdb;
public List<GetStudents_Result> std
{
get { return stdb; }
set { stdb = value; NotifyPropertyChanged("std"); }
}
...