问题
I am wondering if someone can share or point to good samples of datagrid structure that can be used in Silverlight application. I need to have 4 relational datagrids where one of them is master datagrid which has most of the data. I should be able to delete or add or change properties of the items. This changes should also affect other datagrids. For example, if I delete one item from master datagrid then the instance of that item should be deleted from other datagrids. Any information is highly appreciated. Thank you in advance!
回答1:
I had previously created a prototype similar to what you are looking for. I didn't use a DataGrid, I was actually using an ItemsControl, but I think it may be beneficial for you.
What I did is made both of my ItemsControls look at the same data. This way, if I were to delete one object, it would also be removed from the other (since it's the same data source).
Using the MVVM pattern, I approached it like this.
To start off, here's what the two grids look like, they're both showing different representations of the same data.

Here's my MainPage.xaml
<UserControl x:Class="ViewModelDeleteObject.MainPage"
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:ViewModelDeleteObject"
xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<UserControl.DataContext>
<local:MainPage_ViewModel/>
</UserControl.DataContext>
<StackPanel Orientation="Horizontal">
<ItemsControl ItemsSource="{Binding Coordinates}" Margin="20">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Blue" BorderThickness="1">
<StackPanel Orientation="Horizontal" Margin="3">
<Border BorderBrush="Red" BorderThickness="1">
<TextBlock Text="{Binding X}" TextAlignment="Right" Width="100" Margin="3"/>
</Border>
<Border BorderBrush="Red" BorderThickness="1">
<TextBlock Text="{Binding Y}" TextAlignment="Right" Width="100" Margin="3"/>
</Border>
<Button Content="Delete" Click="Button_Click" Tag="{Binding}"/>
</StackPanel>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<ItemsControl ItemsSource="{Binding Coordinates}" Margin="20">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Blue" BorderThickness="1">
<Border BorderBrush="Red" BorderThickness="1">
<TextBlock Text="{Binding XYCoordinate}" TextAlignment="Right" Width="100" Margin="3"/>
</Border>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
this.viewModel = this.DataContext as MainPage_ViewModel;
}
private MainPage_ViewModel viewModel;
private void Button_Click(object sender, RoutedEventArgs e)
{
viewModel.DeleteCoordinate((sender as Button).Tag as Coordinate_DataViewModel);
}
}
MainPage.xaml has the following MainPage_ViewModel.cs set as its DataContext:
public class MainPage_ViewModel : INotifyPropertyChanged
{
public MainPage_ViewModel()
{
coordinates.Add(new Coordinate_DataViewModel(new Coordinate_Model() { X = 1, Y = 2 }));
coordinates.Add(new Coordinate_DataViewModel(new Coordinate_Model() { X = 2, Y = 4 }));
coordinates.Add(new Coordinate_DataViewModel(new Coordinate_Model() { X = 3, Y = 6 }));
coordinates.Add(new Coordinate_DataViewModel(new Coordinate_Model() { X = 4, Y = 8 }));
coordinates.Add(new Coordinate_DataViewModel(new Coordinate_Model() { X = 5, Y = 10 }));
coordinates.Add(new Coordinate_DataViewModel(new Coordinate_Model() { X = 6, Y = 12 }));
}
public ObservableCollection<Coordinate_DataViewModel> Coordinates
{
get { return coordinates; }
set
{
if (coordinates != value)
{
coordinates = value;
OnPropertyChanged("Coordinates");
}
}
}
private ObservableCollection<Coordinate_DataViewModel> coordinates = new ObservableCollection<Coordinate_DataViewModel>();
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public void DeleteCoordinate(Coordinate_DataViewModel dvmToDelete)
{
coordinates.Remove(dvmToDelete);
}
}
My model and data view model classes are also shown below.
Model
public class Coordinate_Model
{
public double X;
public double Y;
}
DataViewModel
public class Coordinate_DataViewModel
{
public Coordinate_DataViewModel(Coordinate_Model model)
{
this.underlyingModel = model;
}
private Coordinate_Model underlyingModel;
public double X
{
get { return underlyingModel.X; }
set { underlyingModel.X = value; }
}
public double Y
{
get { return underlyingModel.Y; }
set { underlyingModel.Y = value; }
}
public string XYCoordinate
{
get { return "(" + X + "," + Y + ")"; }
}
}
Now, when I delete a row from the first grid, the second grid immediately updates as shown below where I deleted the 4,8:

I think this may be similar to what you were thinking. Hope it helps :)
Note: All of the code is here, so you should be able to copy & paste and execute yourself if you'd like.
Update: This solution was written in Silverlight, but I noticed the your question is 'WPF' and its tagged as Silverlight. Even if you're using WPF, this example should still be beneficial. Sorry!
Update: OK, I'll update it to use a DataGrid. This literally took me two minutes to implement with the previous code that was given. The only thing that had to change was the view, please note that no other code was touched.
Here's the new items in the view:
<data:DataGrid ItemsSource="{Binding Coordinates}" AutoGenerateColumns="False" Margin="10">
<data:DataGrid.Columns>
<data:DataGridTextColumn Header="X Position" Width="100" Binding="{Binding X}"/>
<data:DataGridTextColumn Header="Y Position" Width="100" Binding="{Binding Y}"/>
<data:DataGridTemplateColumn Header="Delete Item" Width="100">
<data:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Content="Delete" Tag="{Binding}" Click="Button_Click"/>
</DataTemplate>
</data:DataGridTemplateColumn.CellTemplate>
</data:DataGridTemplateColumn>
</data:DataGrid.Columns>
</data:DataGrid>
<data:DataGrid ItemsSource="{Binding Coordinates}" AutoGenerateColumns="False" Margin="10">
<data:DataGrid.Columns>
<data:DataGridTextColumn Header="Coordinate" Width="100" Binding="{Binding XYCoordinate}"/>
</data:DataGrid.Columns>
</data:DataGrid>
Here's what the initial grids look like:

Here's what it looks like after delete:

来源:https://stackoverflow.com/questions/5264978/interactive-wpf-relational-datagrid-system-samples