【问题标题】:How can I set a dependency property on a static resource?如何在静态资源上设置依赖属性?
【发布时间】:2011-08-19 16:35:58
【问题描述】:

我试图解决我无法为ConverterParameter 指定动态值的事实。 See my other question for why I need to bind a dynamic value to ConverterParameter - 我不喜欢当前发布的解决方案,因为它们都需要对我的视图模型进行不必要的更改。

为了尝试解决这个问题,我创建了一个自定义转换器,并在该转换器上公开了一个依赖属性:

public class InstanceToBooleanConverter : DependencyObject, IValueConverter
{
    public object Value
    {
        get { return (object)GetValue(ValueProperty); }
        set { SetValue(ValueProperty, value); }
    }

    public static readonly DependencyProperty ValueProperty =
        DependencyProperty.Register("Value", typeof(object), typeof(InstanceToBooleanConverter), null);

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return value != null && value.Equals(Value);
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return value.Equals(true) ? Value : Binding.DoNothing;
    }
}

有没有办法在我的 XAML 中使用绑定(或样式设置器或其他疯狂的方法)来设置此值?

<ItemsControl ItemsSource="{Binding Properties}">
    <ItemsControl.ItemTemplate>
        <DataTemplate DataType="{x:Type local:SomeClass}">
            <DataTemplate.Resources>
                <!-- I'd like to set Value to the item from ItemsSource -->
                <local:InstanceToBooleanConverter x:Key="converter" Value="{Binding Path=???}" />
            </DataTemplate.Resources>
<!- ... ->

目前我看到的例子只绑定到静态资源。

编辑:

我收到一些反馈,说我发布的 XAML 只有一个转换器实例。

我可以通过将资源置于我的控制中来解决此问题:

<ItemsControl ItemsSource="{Binding Properties}">
    <ItemsControl.ItemTemplate>
        <DataTemplate DataType="{x:Type local:SomeClass}">
            <RadioButton Content="{Binding Name}" GroupName="Properties">
                <RadioButton.Resources>
                    <!-- I'd like to set Value to the item from ItemsSource -->
                    <local:InstanceToBooleanConverter x:Key="converter"
                                                      Value="{Binding Path=???}" />
                </RadioButton.Resources>
                <RadioButton.IsChecked>
                    <Binding Path="DataContext.SelectedItem"
                             RelativeSource="{RelativeSource AncestorType={x:Type Window}}"
                             Converter="{StaticResource converter}" />
                </RadioButton.IsChecked>
            </RadioButton>
<!- ... ->

所以这个问题不会因为必须共享转换器实例而被阻止:)

【问题讨论】:

    标签: wpf data-binding mvvm ivalueconverter staticresource


    【解决方案1】:

    不幸的是,这是行不通的——我以前一直在走这条路,结果发现 ItemsControl 中的所有项目都共享同一个转换器。我认为这是由于 XAML 解析器的工作方式造成的。

    【讨论】:

    • 是的,我可以看到这是一个问题。但是我注意到如果我将它设置为控件上的资源,那么每个控件都会得到一个实例。如果更有意义,我可以更改我的问题。
    【解决方案2】:

    首先,您可以在更高级别的资源字典中指定转换器并将x:Shared 设置为false,其次,如果您想要“将值设置为 ItemsSource 中的项目”,如您所注释您可以只指定一个空绑定 (Value="{Binding}")。

    【讨论】:

    • 感谢x:Shared 的信息。至于绑定,当我执行Value="{Binding}" 时,我的依赖属性的设置器似乎永远不会被调用。
    • 内部机制不使用依赖属性的设置器,它们仅用于代码隐藏访问。这就是为什么除了 SetValue/GetValue 调用之外,永远不要在其中放入任何代码。
    • 二传手没有被调用是对的。如果我从 Value="{Binding}" 更改为 Value="{StaticResource someOtherResource},getter 会返回该静态资源实例,但永远不会调用 setter。但是当我返回Value="{Binding}" 时,getter 会返回null
    • 没关系,绑定毕竟不是一个值。 (在绑定中的某些点可能不会返回值,所以GetValue 返回null
    • “(在绑定中的某些点可能不会返回值,因此 GetValue 返回 null)”。您是指在应用程序启动/UI 创建期间的某些时间点,还是在运行应用程序的某些时间点?在对此进行测试时,我使用了一个 DataContext(在构造函数中设置),以确保没有任何内容为空。我开始认为这个绑定是在编译时发生的,然后是序列化的。
    猜你喜欢
    • 2013-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-14
    • 2011-12-10
    相关资源
    最近更新 更多