4

In WPF, is it possible to bind the key in "{StaticResource key}"to a variable.

For example. I have a variable ExecutionState with the states Active and Completed.

In my ResourceDictionary I have

<Style TargetType="{x:Type TextBlock}" x:Key="Active">
        <Setter Property="Foreground" Value="Yellow"/>
    </Style>
    <Style TargetType="{x:Type TextBlock}" x:Key="Completed">
        <Setter Property="Foreground" Value="Green"/>
    </Style>

Instead of having

<TextBlock Style="{StaticResource Active}"/>

I Would like to have something like

<TextBlock Style="{StaticResource {Binding ExecutionState}}"/>

Thus if the state changes the text color changes. Is something like this even possible? I can achieve the wanted functionality using triggers, but I have to reuse it at several places and I don't want to clutter my code. I am using MVVM also.

thanx


Given your problem description I figure you bind your ParentObject directly to your components instead of binding a reference to the ParentObject. The serialization/deserialization of session scoped objects (which all pages, components and models in effect are) creates these 'new' instances (even though they are deserialized copies of the original parent object).

While you have not shown much code, I suspect you do something like this:

public MyPage() {
    Object parentObject = ((MyApplication)Application.get()).getParentObject();
    add(new Label("timer", new PropertyModel(parentObject, "time")));
}

This binds the parent object to the property model, and that binds the parent object to the page (through the label component). What you should do instead is:

public MyPage() {
    add(new Label("timer", new PropertyModel(this, "application.parentObject.time")));
}

This binds the page to itself, and instructs the property model to retrieve the application dynamically, and from the application the parent object, and from that the time. This way you don't bind your objects to the page hierarchy, but retrieve them dynamically.

Another option is to use a LoadableDetachableModel that retrieves the parent object from the application, and detaches it after rendering the page.

public class ParentObjectModel extends LoadableDetachableModel<ParentObject> {
    @Override public ParentObject load() {
        return ((MyApplication)Application.get()).getParentObject();
    }
}

See the Wicket wiki for more information on Models.

4

2 回答 2

0

不,这是不可能的。绑定只能在 DependencyProperty 上设置。StaticResource 不是 DependencyObject,因此没有 DependencyProperty。您应该使用触发器或开发自己的附加行为。

于 2012-04-17T10:57:37.107 回答
0

没有直接的方法可以实现。创建一个附加属性并指定要绑定的属性名称。在属性更改回调函数中更新控件样式。

<TextBlock  dep:CustomStyle.StyleName="{Binding ExecutionState}"    Text="Thiru"        />


public static  class CustomStyle
{
    static FrameworkPropertyMetadata _styleMetadata = new FrameworkPropertyMetadata(
                                     string.Empty, FrameworkPropertyMetadataOptions.AffectsRender, StyleNamePropertyChangeCallBack);

    public static readonly DependencyProperty StyleNameProperty =
        DependencyProperty.RegisterAttached("StyleName", typeof (String), typeof (CustomStyle), _styleMetadata);

    public static void SetStyleName(UIElement element, string value)
    {
        element.SetValue(StyleNameProperty, value);
    }
    public static Boolean GetStyleName(UIElement element)
    {
        return (Boolean)element.GetValue(StyleNameProperty);
    }


    public static void StyleNamePropertyChangeCallBack(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {

        FrameworkElement ctrl = d as FrameworkElement;

        if (ctrl.IsLoaded)
        {

            string styleName = Convert.ToString(e.NewValue);
            if (!string.IsNullOrEmpty(styleName))
            {
                ctrl.Style = ctrl.TryFindResource(styleName) as Style;
            }
        }
    }
}
于 2012-04-17T11:17:12.883 回答