<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Silverlight &#124; WPF &#124; Microsoft.Net &#187; ComboBox</title>
	<atom:link href="http://joel.neubeck.net/tag/combobox/feed/" rel="self" type="application/rss+xml" />
	<link>http://joel.neubeck.net</link>
	<description>Simplifing structure without changing results</description>
	<lastBuildDate>Fri, 01 Apr 2011 21:34:22 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1</generator>
		<item>
		<title>Control Visibility with triggers</title>
		<link>http://joel.neubeck.net/2009/08/control-visibility-with-triggers/</link>
		<comments>http://joel.neubeck.net/2009/08/control-visibility-with-triggers/#comments</comments>
		<pubDate>Mon, 10 Aug 2009 21:30:10 +0000</pubDate>
		<dc:creator>joel</dc:creator>
				<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[CheckBox]]></category>
		<category><![CDATA[ComboBox]]></category>
		<category><![CDATA[ListBox]]></category>
		<category><![CDATA[Silverlight 3]]></category>
		<category><![CDATA[TargetedTriggerAction]]></category>

		<guid isPermaLink="false">http://joel.neubeck.net/2009/08/control-visibility-with-triggers/</guid>
		<description><![CDATA[I absolutely love writing triggers for Silverlight 3.&#160; As UX developers we often faced with the challenge of finding ways to fit a ton of information on a single user input screen.&#160; On occasion, some of that information may only be relevant to display if users have made certain choices on the interface: checking a [...]]]></description>
			<content:encoded><![CDATA[<p>I absolutely love writing triggers for Silverlight 3.&#160; As UX developers we often faced with the challenge of finding ways to fit a ton of information on a single user input screen.&#160; On occasion, some of that information may only be relevant to display if users have made certain choices on the interface: checking a box, selecting an item in a combobox or listbox.&#160; In this post I will include two custom TargetedTriggerAction’s which allow a developer to easily tie a UIElement’s visibility to an action made on another control.</p>
<h2>VisibilityIsChecked</h2>
<p>This first trigger I very simple.&#160; I wanted the ability to tie a checkbox to the visibility of another UIElement.&#160; Since a checkbox derives from ToggleButton we can get creative and write a single trigger that will work with either a CheckBox, RadioButton or ToggleButton.&#160; Here is how I did it.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
</pre></td><td class="code"><pre class="c-sharp" style="font-family:monospace;">using System.Windows;
using System.Windows.Controls.Primitives;
using System.Windows.Interactivity;
&nbsp;
namespace VisibilityTriggers
{
    public class VisibilityIsChecked : TargetedTriggerAction&lt;frameworkelement&gt;
    {
        public static readonly DependencyProperty VisibleWhenCheckedProperty =
            DependencyProperty.Register(&amp;quot;VisibleWhenChecked&amp;quot;, typeof(bool), 
            typeof(VisibilityIsChecked), new PropertyMetadata(true));
        public bool VisibleWhenChecked
        {
            get
            {
                return (bool)GetValue(VisibleWhenCheckedProperty);
            }
            set
            {
                SetValue(VisibleWhenCheckedProperty, value);
            }
        }
&nbsp;
        protected override void OnAttached()
        {
            base.OnAttached();
            FrameworkElement element = this.AssociatedObject as FrameworkElement;
            if (element != null) element.Loaded += TargetLoaded;
        }
&nbsp;
        void TargetLoaded(object sender, RoutedEventArgs e)
        {
            ToggleButton tb = this.AssociatedObject as ToggleButton;
            SetVisibility(tb);
        }
        protected override void Invoke(object parameter)
        {
            RoutedEventArgs args = parameter as RoutedEventArgs;
&nbsp;
            if (args != null)
            {
                ToggleButton tb = args.OriginalSource as ToggleButton;
                SetVisibility(tb);
            }
        }
&nbsp;
        private void SetVisibility(ToggleButton tb)
        {
            if (tb != null)
            {
                Target.Visibility = ((bool)tb.IsChecked == VisibleWhenChecked) ? 
                Visibility.Visible : Visibility.Collapsed;
            }
        }
    }
}</pre></td></tr></table></div>

<p>To implement this trigger, we simply add an EventTrigger to a checkbox and set the TargetName to the control I want to visualize. Since there are times that we want IsChecked to either show or hide the element I have included a DependencyProperty called VisibileWhenChecked that can alter this behavior.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre class="c-sharp" style="font-family:monospace;">&lt;checkbox content=&quot;Show?&quot; margin=&quot;5&quot;&gt;
    &lt;i:interaction.triggers&gt;
        &lt;i:eventtrigger eventname=&quot;Click&quot;&gt;
            &lt;triggers:visibilityischecked targetname=&quot;rectangle&quot; /&gt;
        &lt;/i:eventtrigger&gt;
    &lt;/i:interaction.triggers&gt;
&lt;/checkbox&gt;
&lt;rectangle margin=&quot;10&quot; x:name=&quot;rectangle&quot; width=&quot;100&quot; height=&quot;100&quot; fill=&quot;Yellow&quot; visibility=&quot;Collapsed&quot; /&gt;</pre></td></tr></table></div>

<h2>VisibilitySelectedItem</h2>
<p>The second TargetedTriggerAction I created achieves a similar result, but instead of targeting a checkbox or radio button, it targets a ComboBox or ListBox. In this trigger I will flip a UIElements visibility based on a specific value being returned from a selection in the the ListBox. Here is how I implemented the trigger.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
</pre></td><td class="code"><pre class="c-sharp" style="font-family:monospace;">using System.Collections;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Interactivity;
&nbsp;
namespace VisibilityTriggers
{
    public class VisibilitySelectedItem : TargetedTriggerAction&lt;frameworkelement&gt;
    {
        public static readonly DependencyProperty ValueProperty =
            DependencyProperty.Register(&amp;quot;Value&amp;quot;, typeof(object), typeof(VisibilitySelectedItem), null);
&nbsp;
        public object Value
        {
            get
            {
                return (object)GetValue(ValueProperty);
            }
            set
            {
                SetValue(ValueProperty, value);
            }
        }
&nbsp;
        public static readonly DependencyProperty MatchMemberPathProperty =
            DependencyProperty.Register(&amp;quot;MatchMemberPath&amp;quot;, typeof(string), typeof(VisibilitySelectedItem), new PropertyMetadata(&amp;quot;Content&amp;quot;));
&nbsp;
        public string MatchMemberPath
        {
            get
            {
                return (string)GetValue(MatchMemberPathProperty);
            }
            set
            {
                SetValue(MatchMemberPathProperty, value);
            }
        }
&nbsp;
        protected override void OnAttached()
        {
            base.OnAttached();
            FrameworkElement element = this.AssociatedObject as FrameworkElement;
            if (element != null) element.Loaded += TargetLoaded;
        }
&nbsp;
        void TargetLoaded(object sender, RoutedEventArgs e)
        {
            FrameworkElement element = this.AssociatedObject as FrameworkElement;
            Selector cb = this.Target as Selector;
            if (cb != null)
            {
                int index = cb.SelectedIndex &amp;gt; -1 ? cb.SelectedIndex : 0;
                object item = (cb.Items.Count &amp;gt; 0) ? cb.Items[index] as object : null;
&nbsp;
                if (item != null)
                {
                    System.Reflection.PropertyInfo pi = item.GetType().GetProperty(MatchMemberPath);
                    var value = (pi != null) ? pi.GetValue(item, null) as object : item;
                    bool match = Equals(value, Value);
                    if (element != null) element.Visibility = match ? Visibility.Visible : Visibility.Collapsed;
                }
            }
        }
        protected override void Invoke(object parameter)
        {
            FrameworkElement element = this.AssociatedObject as FrameworkElement;
            SelectionChangedEventArgs args = parameter as SelectionChangedEventArgs;
&nbsp;
            if (args != null)
            {
                IList list = args.AddedItems as IList;
                if (list != null)
                {
                    foreach (object item in list)
                    {
                        System.Reflection.PropertyInfo pi = item.GetType().GetProperty(MatchMemberPath);
                        var value = (pi != null) ? pi.GetValue(item, null) as object : item;
&nbsp;
                        bool match = Equals(value, Value);
                        if (element != null) element.Visibility = match ? Visibility.Visible : Visibility.Collapsed;
                    }
                }
            }
        }
    }
}</pre></td></tr></table></div>

<p>To implement this TargetedTriggerAction you will place the custom EventTrigger on the item you want to visualize and target the SelectionChanged event on the ListBox (or ComboBox). Since we only want to visualize when a specific value is returned, we will also specifiy a &quot;Value&quot; and which property of our ListBox&#8217;s ItemSource we are targeting (MatchMemeberPath). The following is one way in which we can implement the trigger.&#160;</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
</pre></td><td class="code"><pre class="c-sharp" style="font-family:monospace;">&lt;listbox x:name=&quot;myComboBox2&quot; width=&quot;100&quot; itemssource=&quot;{Binding Path=Items}&quot; displaymemberpath=&quot;Description&quot; /&gt;
&lt;rectangle margin=&quot;10&quot; width=&quot;100&quot; height=&quot;100&quot; fill=&quot;Silver&quot; visibility=&quot;Collapsed&quot;&gt;
    &lt;i:interaction.triggers&gt;
        &lt;i:eventtrigger eventname=&quot;SelectionChanged&quot; sourcename=&quot;myComboBox2&quot;&gt;
            &lt;triggers:visibilityselecteditem targetname=&quot;myComboBox2&quot; value=&quot;I1&quot; matchmemberpath=&quot;Code&quot; /&gt;
        &lt;/i:eventtrigger&gt;
    &lt;/i:interaction.triggers&gt;
&lt;/rectangle&gt;
&lt;ellipse margin=&quot;10&quot; width=&quot;100&quot; height=&quot;100&quot; fill=&quot;SaddleBrown&quot; visibility=&quot;Collapsed&quot;&gt;
    &lt;i:interaction.triggers&gt;
        &lt;i:eventtrigger eventname=&quot;SelectionChanged&quot; sourcename=&quot;myComboBox2&quot;&gt;
            &lt;triggers:visibilityselecteditem targetname=&quot;myComboBox2&quot; value=&quot;I2&quot; matchmemberpath=&quot;Code&quot; /&gt;
        &lt;/i:eventtrigger&gt;
    &lt;/i:interaction.triggers&gt;
&lt;/ellipse&gt;</pre></td></tr></table></div>

<p><br style="clear: both" /><iframe height="300" src="/wp-content/uploads/2009/08/VisibilityTriggers/" width="500"></iframe><br />
<br style="clear: both" /><br />
Code: <a onclick="javascript:pageTracker._trackPageview(&#39;/code/VisibilityTriggers.zip&#39;); " href="/wp-content/uploads/2009/08/VisibilityTriggers/VisibilityTriggers.zip">VisibilityTriggers.zip</a></p>
]]></content:encoded>
			<wfw:commentRss>http://joel.neubeck.net/2009/08/control-visibility-with-triggers/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>

