微软的兄弟很认真,对Silverlight4总想很好的兼容Silverlight2,3,因为WP7是用的Silverlight3,所以Setter里面还是不能实现绑定(在WPF中很容易),不过这个问题在Silverlight5里面会得到解决(见《Binding on Style Setter in Silverlight5》)。比如下面的代码在Silverlight5之前不能工作:
1: <ListBox x:Name="theBox" DisplayMemberPath="Name">
2: <ListBox.ItemContainerStyle>
3: <Style TargetType="ListBoxItem">
4: <Setter Property="IsEnabled" Value="{Binding}" />
5: </Style>
6: </ListBox.ItemContainerStyle>
7: </ListBox>
如果你使用MVVM模式来开发,那么Listbox里面的ListItem集合肯定是绑定到ViewModel的某个集合。对每个ListboxItem.IsEnabled属性绑定自然也就是绑定到这个集合元素的某个属性了。具体的做法是这样:
好了,来看看ItemContainerStyle,里面最好能绑定ListboxItem.IsEnabled属性
OK,这就要Silverlight4下面Setter不能实现绑定的问题,在Silverlight5里面会得到解决。现在怎么办呢?写个类,叫做:SetterValueBindingHelper
1: using System;
2: using System.Collections.Generic;
3: using System.Collections.ObjectModel;
4: using System.Diagnostics.CodeAnalysis;
5: using System.Globalization;
6: using System.Linq;
7: using System.Reflection;
8: using System.Windows;
9: using System.Windows.Controls;
10: using System.Windows.Data;
11: using System.Windows.Markup;
12:
13: namespace SilverlightApplication1
14: {
15: /// <summary>
16: /// Class that implements a workaround for a Silverlight XAML parser
17: /// limitation that prevents the following syntax from working:
18: /// <Setter Property="IsSelected" Value="{Binding IsSelected}"/>
19: /// </summary>
20: [ContentProperty("Values")]
21: public class SetterValueBindingHelper
22: {
23: /// <summary>
24: /// Optional type parameter used to specify the type of an attached
25: /// DependencyProperty as an assembly-qualified name, full name, or
26: /// short name.
27: /// </summary>
28: [SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods",
29: Justification = "Unambiguous in XAML.")]
30: public string Type { get; set; }
31:
32: /// <summary>
33: /// Property name for the normal/attached DependencyProperty on which
34: /// to set the Binding.
35: /// </summary>
36: public string Property { get; set; }
37:
38: /// <summary>
39: /// Binding to set on the specified property.
40: /// </summary>
41: public Binding Binding { get; set; }
42:
43: /// <summary>
44: /// Collection of SetterValueBindingHelper instances to apply to the
45: /// target element.
46: /// </summary>
47: /// <remarks>
48: /// Used when multiple Bindings need to be applied to the same element.
49: /// </remarks>
50: public Collection<SetterValueBindingHelper> Values
51: {
52: get
53: {
54: // Defer creating collection until needed
55: if (null == _values)
56: {
57: _values = new Collection<SetterValueBindingHelper>();
58: }
59: return _values;
60: }
61: }
62: private Collection<SetterValueBindingHelper> _values;
63:
64: /// <summary>
65: /// Gets the value of the PropertyBinding attached DependencyProperty.
66: /// </summary>
67: /// <param name="element">Element for which to get the property.</param>
68: /// <returns>Value of PropertyBinding attached DependencyProperty.</returns>
69: [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters",
70: Justification = "SetBinding is only available on FrameworkElement.")]
71: public static SetterValueBindingHelper GetPropertyBinding(FrameworkElement element)
72: {
73: if (null == element)
74: {
75: throw new ArgumentNullException("element");
76: }
77: return (SetterValueBindingHelper)element.GetValue(PropertyBindingProperty);
78: }
79:
80: /// <summary>
81: /// Sets the value of the PropertyBinding attached DependencyProperty.
82: /// </summary>
83: /// <param name="element">Element on which to set the property.</param>
84: /// <param name="value">Value forPropertyBinding attached DependencyProperty.</param>
85: [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters",
86: Justification = "SetBinding is only available on FrameworkElement.")]
87: public static void SetPropertyBinding(FrameworkElement element, SetterValueBindingHelper value)
88: {
89: if (null == element)
90: {
91: throw new ArgumentNullException("element");
92: }
93: element.SetValue(PropertyBindingProperty, value);
94: }
95:
96: /// <summary>
97: /// PropertyBinding attached DependencyProperty.
98: /// </summary>
99: public static readonly DependencyProperty PropertyBindingProperty =
100: DependencyProperty.RegisterAttached(
101: "PropertyBinding",
102: typeof(SetterValueBindingHelper),
103: typeof(SetterValueBindingHelper),
104: new PropertyMetadata(null, OnPropertyBindingPropertyChanged));