Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Build your own custom filter control. First, get rid of the enum, use a custom class instead, that defines your available filter options. I choose a class named "FilterOption", which has a property named "ColumnCriteriaName". You would create a list of those somewhere in your application.</p> <pre><code>public class FilterOption { public string ColumnNameCriteria { get; set; } } </code></pre> <p>Now its time to create your custom silverlight control. The purpose of this control is the accept a list of FilterOptions and display a set of Radiobuttons. Each button will be a FilterOption value. When the user selects a value, you will get notified. This control will use the Commanding techniques i tried to describe.</p> <p>Add a new control, name it "FilterOptionControl.xaml". The Xaml Code is as follows:</p> <pre><code>&lt;UserControl x:Class="SilverlightApplication1.FilterOptionControl" 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" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="400"&gt; &lt;Grid x:Name="LayoutRoot" Background="White"&gt; &lt;StackPanel x:Name="stacker" /&gt; &lt;/Grid&gt; &lt;/UserControl&gt; </code></pre> <p>Its just an empty control with a Stackpanel which will hold our RadioButtons which we will create at runtime. Also please note that i will not use MVVM for this custom control, because in this case it would be over-engineering. Of course, feel free to add MVVM to this control if you want to, but i really dont recommend it. You should however use MVVM in your more domain specific controls. </p> <p>Enought talk, lets just paste in the .cs code for your custom control</p> <pre><code>public partial class FilterOptionControl : UserControl { public IEnumerable&lt;FilterOption&gt; AvailableOptions { get { return (IEnumerable&lt;FilterOption&gt;)GetValue(AvailableOptionsProperty); } set { SetValue(AvailableOptionsProperty, value); } } public static readonly DependencyProperty AvailableOptionsProperty = DependencyProperty.Register( "AvailableOptions", typeof(IEnumerable&lt;FilterOption&gt;), typeof(FilterOptionControl), new PropertyMetadata(OnPropertyChangedCallback)); public FilterOption SelectedOption { get { return (FilterOption)GetValue(SelectedOptionProperty); } set { SetValue(SelectedOptionProperty, value); } } public static readonly DependencyProperty SelectedOptionProperty = DependencyProperty.Register( "SelectedOption", typeof(FilterOption), typeof(FilterOptionControl), new PropertyMetadata(OnPropertyChangedCallback)); protected static void OnPropertyChangedCallback(DependencyObject sender, DependencyPropertyChangedEventArgs args) { if (sender is FilterOptionControl) ((FilterOptionControl)sender).OnPropertyChanged(args); } private void OnPropertyChanged(DependencyPropertyChangedEventArgs args) { if (args.Property == AvailableOptionsProperty) { RebuildFilterOptions(); } } public FilterOptionControl() { InitializeComponent(); SelectedValueChangedCommand = new RelayCommand( new Action&lt;object&gt;(this.ChangeSelectedValue)); } RelayCommand SelectedValueChangedCommand; void ChangeSelectedValue(object option) { SelectedOption = option as FilterOption; } private void RebuildFilterOptions() { stacker.Children.Clear(); if (AvailableOptions != null) { foreach (FilterOption option in AvailableOptions) { RadioButton btt = new RadioButton(); btt.Content = option.ColumnNameCriteria; btt.Command = SelectedValueChangedCommand; btt.CommandParameter = option; stacker.Children.Add(btt); } } } } </code></pre> <p>As you can see we have two dependency properties which are both wired up with changed events so we get notified when they get set (this way you could set an initial value for the filter options - however i didnt implement it straight away, youll have to do this yourself). </p> <p>If we get set any FilterOptions on the AvailableOptions Property, we will trigger our build mechanism. We clear the StackPanel and add a new RadioButton for every FilterOption. Additionally we wire up a RelayCommand with this RadioButtons (see <a href="http://msdn.microsoft.com/en-us/magazine/dd419663.aspx#id0090051" rel="nofollow">http://msdn.microsoft.com/en-us/magazine/dd419663.aspx#id0090051</a> for command explanation) and set the CommandParameter to the respective FilterOption.</p> <p>So if a RadioButton gets clicked, this command gets fired with the corresponding FilterOption set as the CommandParameter. We now set the SelectedOption of our control to this new value.</p> <p>The code for the RelayCommand is here, but is taken (and slightly modified) from the msdn link i posted above</p> <pre><code>public class RelayCommand : ICommand { readonly Action&lt;object&gt; _execute; readonly Predicate&lt;object&gt; _canExecute; public RelayCommand(Action&lt;object&gt; execute) : this(execute, null) { } public RelayCommand(Action&lt;object&gt; execute, Predicate&lt;object&gt; canExecute) { if (execute == null) throw new ArgumentNullException("execute"); _execute = execute; _canExecute = canExecute; } public bool CanExecute(object parameter) { return _canExecute == null ? true : _canExecute(parameter); } public event EventHandler CanExecuteChanged; public void Execute(object parameter) { _execute(parameter); } } </code></pre> <p>Now you are ready to use this control on a page as you like. I did it like so in the main page of my test app:</p> <pre><code>&lt;UserControl x:Class="SilverlightApplication1.MainPage" *snip* x:Name="me"&gt; &lt;Grid x:Name="LayoutRoot" Background="White"&gt; &lt;StackPanel&gt; &lt;TextBlock Text="{Binding ElementName=filter, Path=SelectedOption.ColumnNameCriteria, FallbackValue='none'}"/&gt; &lt;this:FilterOptionControl x:Name="filter" AvailableOptions="{Binding ElementName=me, Path=MyFilterOptions}" /&gt; &lt;/StackPanel&gt; &lt;/Grid&gt; &lt;/UserControl&gt; </code></pre> <p>and the code behind looks like this:</p> <pre><code>public partial class MainPage : UserControl { public IEnumerable&lt;FilterOption&gt; MyFilterOptions { get { return (IEnumerable&lt;FilterOption&gt;)GetValue(MyFilterOptionsProperty); } set { SetValue(MyFilterOptionsProperty, value); } } public static readonly DependencyProperty MyFilterOptionsProperty = DependencyProperty.Register( "MyFilterOptions", typeof(IEnumerable&lt;FilterOption&gt;), typeof(MainPage), new PropertyMetadata(null)); public MainPage() { InitializeComponent(); MyFilterOptions = new List&lt;FilterOption&gt; { new FilterOption() { ColumnNameCriteria = "One"}, new FilterOption() { ColumnNameCriteria = "Two"}, new FilterOption() { ColumnNameCriteria = "Three"} }; } } </code></pre> <p>I hope that helped. </p> <p>it: Of course, if you still want to use your enums, you can do so too using the FilterOption class, but this code should be a good start for your i hope.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload