I have a problem getting the raddatafilter to work properly in unbound mode. I want to use your datafilter to filter a DomainDataSource, which is in my viewmodel, so I created a custom control that inherits from RDF, and into which I pasted and adapted the code from the demo at http://demos.telerik.com/silverlight/#DataFilter/DomainDataSource . Now I have two problems. First, the user has to click twice on the remove button to remove a filter. For example, if I've added a filter to filter the datagrid based on a particular ItemID, the first click on the "X" removes the filter from the DDS and the datagrid is refreshed. But the filter is still present in the UI until the user clicks a 2nd time on the X.
The 2nd problem is that the DDS is not automatically refreshed when the filters and filter collection are altered. I can workaround this by adding a Load method or a separate button that calls Load but I would prefer to see if there's a better way to do this. Below is snippets of my xaml and my custom datafilter class.
The 2nd problem is that the DDS is not automatically refreshed when the filters and filter collection are altered. I can workaround this by adding a Load method or a separate button that calls Load but I would prefer to see if there's a better way to do this. Below is snippets of my xaml and my custom datafilter class.
public class DatagridFilter: RadDataFilter
{
private Dictionary<
Telerik.Windows.Data.FilterDescriptor
, System.Windows.Controls.FilterDescriptor> filterMap
= new Dictionary<
Telerik.Windows.Data.FilterDescriptor
, System.Windows.Controls.FilterDescriptor>();
DomainDataSource dds;
public DatagridFilter()
{
this.CanUserCreateCompositeFilters = false;
this.FilterDescriptors.PropertyChanged += this.OnFilterDescriptorsPropertyChanged;
// Hook up the FilterDescriptors
this.FilterDescriptors.CollectionChanged += this.OnFilterDescriptorsCollectionChanged;
this.FilterOperatorsLoading += new EventHandler<
FilterOperatorsLoadingEventArgs
>(DatagridFilter_FilterOperatorsLoading);
}
void DatagridFilter_FilterOperatorsLoading(object sender, FilterOperatorsLoadingEventArgs e)
{
Telerik.Windows.Data.FilterOperator f1 = Telerik.Windows.Data.FilterOperator.DoesNotContain;
Telerik.Windows.Data.FilterOperator f2 = Telerik.Windows.Data.FilterOperator.IsContainedIn;
Telerik.Windows.Data.FilterOperator f3 = Telerik.Windows.Data.FilterOperator.IsNotContainedIn;
Telerik.Windows.Data.FilterOperator f4 = Telerik.Windows.Data.FilterOperator.EndsWith;
//Telerik.Windows.Data.FilterOperator f4 = Telerik.Windows.Data.FilterOperator.Contains;
e.AvailableOperators.Remove(f1);
e.AvailableOperators.Remove(f2);
e.AvailableOperators.Remove(f3);
e.AvailableOperators.Remove(f4);
}
private void OnFilterDescriptorsPropertyChanged(object sender, PropertyChangedEventArgs e)
{
ICompositeFilterDescriptor cfd = (ICompositeFilterDescriptor)sender;
SetDDS(cfd);
if (e.PropertyName == "LogicalOperator")
{
this.dds.FilterOperator = CreateRIALogicalOperator(cfd.LogicalOperator);
}
}
void SetDDS(ICompositeFilterDescriptor cfd)
{
if (dds == null)
{
var vm = this.DataContext as IListBaseVM;
if (vm != null)
{
dds = vm.VMDatasource;
if (dds != null && dds.CanLoad)
{
dds.FilterOperator = CreateRIALogicalOperator(cfd.LogicalOperator);
}
}
}
}
private void OnFilterDescriptorsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
ICompositeFilterDescriptor cfd = (ICompositeFilterDescriptor)sender;
SetDDS(cfd);
switch (e.Action)
{
case NotifyCollectionChangedAction.Add:
foreach (Telerik.Windows.Data.FilterDescriptor filterDescriptor
in e.NewItems.OfType<
Telerik.Windows.Data.FilterDescriptor
>())
{
this.AddFilter(filterDescriptor);
}
break;
case NotifyCollectionChangedAction.Remove:
foreach (Telerik.Windows.Data.FilterDescriptor filterDescriptor
in e.OldItems.OfType<
Telerik.Windows.Data.FilterDescriptor
>())
{
this.RemoveFilter(filterDescriptor);
}
break;
case NotifyCollectionChangedAction.Reset:
this.dds.FilterDescriptors.Clear();
foreach (Telerik.Windows.Data.FilterDescriptor filterDescriptor in cfd.FilterDescriptors)
{
this.AddFilter(filterDescriptor);
}
break;
}
ReloadData();
}
private void AddFilter(Telerik.Windows.Data.FilterDescriptor filterDescriptor)
{
// Create the corresponding RIA filter based on the Telerik one.
System.Windows.Controls.FilterDescriptor riaFilterDescriptor =
CreateRIAFilterDescriptor(filterDescriptor);
// Link them together so that we can find the RIA one when the
// Telerik one fires PropertyChanged, i.e. you change its operator, value, etc.
this.filterMap[filterDescriptor] = riaFilterDescriptor;
// Listen for property changes, i.e. member, operator, value, etc.
filterDescriptor.PropertyChanged += this.OnFilterDescriptorPropertyChanged;
// We will add the descriptor, once it becomes active, i.e. when its
// value becomes something different from FilterDescriptor.UnsetValue
}
private void RemoveFilter(Telerik.Windows.Data.FilterDescriptor filterDescriptor)
{
// Find the corresponding RIA filter from the hashtable.
System.Windows.Controls.FilterDescriptor riaFilterDescriptor = this.filterMap[filterDescriptor];
// Delete it from the map, since it is going away.
this.filterMap[filterDescriptor] = null;
// Unhook the event listener because we will no longer need it.
filterDescriptor.PropertyChanged -= this.OnFilterDescriptorPropertyChanged;
// Finally, remove the RIA filter from the DomainDataSource.
this.dds.FilterDescriptors.Remove(riaFilterDescriptor);
}
private void OnFilterDescriptorPropertyChanged(object sender, PropertyChangedEventArgs e)
{
Telerik.Windows.Data.FilterDescriptor filterDescriptor = (Telerik.Windows.Data.FilterDescriptor)sender;
// Find the corresponding RIA filter from the hashtable.
System.Windows.Controls.FilterDescriptor riaFilterDescriptor = this.filterMap[filterDescriptor];
switch (e.PropertyName)
{
case "Member":
riaFilterDescriptor.PropertyPath = filterDescriptor.Member;
break;
case "Operator":
riaFilterDescriptor.Operator = CreateRIAOperator(filterDescriptor.Operator);
break;
case "Value":
// DDS is picky about these kinds of things.
if (filterDescriptor.Value == null
&& filterDescriptor.Operator != Telerik.Windows.Data.FilterOperator.IsEqualTo
&& filterDescriptor.Operator != Telerik.Windows.Data.FilterOperator.IsNotEqualTo)
{
filterDescriptor.Value = Telerik.Windows.Data.FilterDescriptor.UnsetValue;
}
riaFilterDescriptor.Value = filterDescriptor.Value;
// In case this filter is being activated for the first time -- add it.
if (!Telerik.Windows.Data.FilterDescriptor.UnsetValue.Equals(riaFilterDescriptor.Value)
&& !this.dds.FilterDescriptors.Contains(riaFilterDescriptor))
{
this.dds.FilterDescriptors.Add(riaFilterDescriptor);
}
break;
case "IsCaseSensitive":
riaFilterDescriptor.IsCaseSensitive = filterDescriptor.IsCaseSensitive;
break;
}
if (riaFilterDescriptor.PropertyPath != null && riaFilterDescriptor.Operator != null && riaFilterDescriptor.Value != null)
{
ReloadData();
}
}
void ReloadData()
{
//if (dds != null && dds.CanLoad)
//{
// dds.Load();
//}
}
private static System.Windows.Controls.FilterOperator CreateRIAOperator(Telerik.Windows.Data.FilterOperator filterOperator)
{
return (System.Windows.Controls.FilterOperator)Enum.Parse(typeof(System.Windows.Controls.FilterOperator), filterOperator.ToString(), true);
}
private static System.Windows.Controls.FilterDescriptorLogicalOperator CreateRIALogicalOperator(Telerik.Windows.Data.FilterCompositionLogicalOperator logicalOperator)
{
return (System.Windows.Controls.FilterDescriptorLogicalOperator)Enum.Parse(typeof(Telerik.Windows.Data.FilterCompositionLogicalOperator), logicalOperator.ToString(), true);
}
private static System.Windows.Controls.FilterDescriptor CreateRIAFilterDescriptor(Telerik.Windows.Data.FilterDescriptor filterDescriptor)
{
System.Windows.Controls.FilterDescriptor riaFilterDescriptor = new System.Windows.Controls.FilterDescriptor();
riaFilterDescriptor.PropertyPath = filterDescriptor.Member;
riaFilterDescriptor.Operator = CreateRIAOperator(filterDescriptor.Operator);
riaFilterDescriptor.Value = filterDescriptor.Value;
riaFilterDescriptor.IsCaseSensitive = filterDescriptor.IsCaseSensitive;
// This is very important. Telerik filters are born with a value equal to
// Telerik.Windows.Data.FilterDescriptor.UnsetValue. Set this to be the
// IgnoredValue value so that the DomainDataSource knows that such filters
// are not yet active.
riaFilterDescriptor.IgnoredValue = Telerik.Windows.Data.FilterDescriptor.UnsetValue;
return riaFilterDescriptor;
}
}
<
local:DatagridFilter
x:Name
=
"dgFilter"
>
<
local:DatagridFilter.ItemPropertyDefinitions
>
<
telerikFilter:ItemPropertyDefinition
PropertyName
=
"ItemID"
DisplayName
=
"ItemID"
PropertyType
=
"{Binding Int32, Source={StaticResource PropertyTypes}}"
/>
</
local:DatagridFilter.ItemPropertyDefinitions
>
</
local:DatagridFilter
>
<
telerikGridView:RadGridView
>
<
telerikGridView:RadGridView.Columns
>
<
telerikGridView:GridViewDataColumn
Header
=
"Item ID"
DataMemberBinding
=
"{Binding ItemID}"
/>
</
telerikGridView:RadGridView.Columns
>
</
telerikGridView:RadGridView
>