If you bind a XamDataGrid to a datatable, the grid will not show any data rows where RowState=Deleted. This is the default behavior and it's very useful. But sometimes you want similar functionality when bound to a collection of objects. One way to do this is with RecordFilters.
RecordFilters allow you to filter out rows that meet certain criteria. If we have a property in the collection that tracks a member's state, we can filter on that. This is just one of many uses of RecordFilters. Consider a collection of cItem where the cItem class is defined like this.
{
Added,
Unchanged,
Modified,
Deleted
}
public cItem(int i)
this.ID = i;
get { return _ObjectState; }
}
The setters for ID, Code and Description would normally call SetProperty and also set ObjectState = Modified, but we've left that out.
cNotifyPropertyChanged is just a base class that implements INotifyPropertyChanged. You already have this right?
namespace RecordFilters
public class cNotifyPropertyChanged:INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
if (!Object.Equals(storage, value))
storage = value;
if (PropertyChanged != null)
}
}
}
The XAML is simply a XamDataGrid that displays a collection of cItems. Note the RecordFilter that only includes Items with ObjectState not Deleted. RecordFilter only acts on a field in the FieldLayout so we have to add a hidden field containing the ObjectState. I don't see a way to bind a RecordFilter to a property in the DataItem.
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:RecordFilters"
xmlns:igDP="http://infragistics.com/DataPresenter"
xmlns:igWindows="http://infragistics.com/Windows"
mc:Ignorable="d"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
Title="Click on a row to delete it" Height="450" Width="800">
<igDP:XamDataGrid DataSource="{Binding Items}"
ActiveDataItem="{Binding ActiveItem}">
<igDP:XamDataGrid.FieldSettings>
<igDP:FieldSettings AllowEdit="False"/>
</igDP:XamDataGrid.FieldSettings>
<igDP:XamDataGrid.FieldLayoutSettings>
<igDP:FieldLayoutSettings AutoGenerateFields="False"/>
</igDP:XamDataGrid.FieldLayoutSettings>
<igDP:XamDataGrid.FieldLayouts>
<igDP:FieldLayout>
<igDP:FieldLayout.RecordFilters>
<igDP:RecordFilter FieldName="ObjectState">
<igDP:RecordFilter.Conditions>
<igWindows:ComparisonCondition Operator="NotEquals" Value="Deleted"/>
</igDP:RecordFilter.Conditions>
</igDP:RecordFilter>
</igDP:FieldLayout.RecordFilters>
<igDP:FieldLayout.Fields>
<igDP:Field Name="ObjectState" Visibility="Collapsed"/>
<igDP:NumericField Name="ID" Width="auto"/>
<igDP:TextField Name="Code" Width="auto"/>
<igDP:TextField Name="Description" Width="*"/>
</igDP:FieldLayout.Fields>
</igDP:FieldLayout>
</igDP:XamDataGrid.FieldLayouts>
</igDP:XamDataGrid>
</Window>
Clicking on a row (setting ActiveItem) will set the ObjectState to deleted. This causes the grid to remove the row you clicked on. Note, the row is still in the collection but it's not visible in the grid. This effectively reproduces the behavior of DataRows. Here's the code behind.
using System.Windows;
namespace RecordFilters
public enum eObjectState
{
Added,
Unchanged,
Modified,
Deleted
}
public class cItem : cNotifyPropertyChanged
public cItem(int i)
this.ID = i;
public int ID { get; set; }
private eObjectState _ObjectState;
get { return _ObjectState; }
}
public partial class MainWindow : Window
public ObservableCollection<cItem> Items { get; set; } = new ObservableCollection<cItem>
new cItem(1),
public cItem ActiveItem
get { return null; }
public MainWindow()
InitializeComponent();
}
}
}
This is how it looks when you run it...
... and after clicking on the second row...
No comments:
Post a Comment