一尘不染

样式设置器中的UWP绑定不起作用

c#

我在创建xaml控件时遇到问题。我正在用通用应用程序在VS
2015中编写新项目。我要创建网格。在此网格中,我想有一个按钮。在模型中,我指定列(级别)和行。这是我的代码:

<ItemsControl Grid.Row="1" ItemsSource="{Binding Path=TechnologyList}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="10*"/>
                    <RowDefinition Height="10*"/>
                    <RowDefinition Height="10*"/>
                    <RowDefinition Height="10*"/>
                    <RowDefinition Height="10*"/>
                    <RowDefinition Height="10*"/>
                    <RowDefinition Height="10*"/>
                    <RowDefinition Height="10*"/>
                    <RowDefinition Height="10*"/>
                    <RowDefinition Height="10*"/>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="14*"/>
                    <ColumnDefinition Width="14*"/>
                    <ColumnDefinition Width="14*"/>
                    <ColumnDefinition Width="14*"/>
                    <ColumnDefinition Width="14*"/>
                    <ColumnDefinition Width="14*"/>
                    <ColumnDefinition Width="14*"/>
                </Grid.ColumnDefinitions>
            </Grid>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemContainerStyle>
        <Style TargetType="Control">
            <Setter Property="Grid.Column" Value="{Binding Level}" />
            <Setter Property="Grid.Row" Value="{Binding Row}" />
        </Style>
    </ItemsControl.ItemContainerStyle>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Button Content="{Binding Name}"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

我在行中收到错误<Setter Property="Grid.Column" Value="{Binding Level}" />
错误:来自HRESULT的异常:0x8000FFFF(E_UNEXPECTED)在edytor中,不在运行代码中。怎么了?在“旧”
WPF中,一切正常,但是在适用于Windows 10的Universal App中,我出现了错误。谁能帮我 ?


阅读 236

收藏
2020-05-19

共1个答案

一尘不染

如MSDN 上Setter.Value属性页上的“ 迁移说明 ”部分所述,UWP /
Windows运行时不支持样式设置器中的绑定。

Windows Presentation Foundation(WPF)和Microsoft
Silverlight支持使用Binding表达式为样式中的Setter提供值的功能。Windows运行时不支持Setter.Value的绑定用法(该绑定不会评估,该Setter无效,您不会收到错误,但也不会获得所需的结果)。从WPF或Silverlight
XAML转换XAML样式时,请使用设置值的字符串或对象替换任何绑定表达式用法,或将这些值重构为共享的{StaticResource}标记扩展值,而不是绑定获得的值。

解决方法可能是为绑定的源路径附加属性的帮助程序类。它在helper属性的PropertyChangedCallback中的代码后面创建绑定:

public class BindingHelper
{
    public static readonly DependencyProperty GridColumnBindingPathProperty =
        DependencyProperty.RegisterAttached(
            "GridColumnBindingPath", typeof(string), typeof(BindingHelper),
            new PropertyMetadata(null, GridBindingPathPropertyChanged));

    public static readonly DependencyProperty GridRowBindingPathProperty =
        DependencyProperty.RegisterAttached(
            "GridRowBindingPath", typeof(string), typeof(BindingHelper),
            new PropertyMetadata(null, GridBindingPathPropertyChanged));

    public static string GetGridColumnBindingPath(DependencyObject obj)
    {
        return (string)obj.GetValue(GridColumnBindingPathProperty);
    }

    public static void SetGridColumnBindingPath(DependencyObject obj, string value)
    {
        obj.SetValue(GridColumnBindingPathProperty, value);
    }

    public static string GetGridRowBindingPath(DependencyObject obj)
    {
        return (string)obj.GetValue(GridRowBindingPathProperty);
    }

    public static void SetGridRowBindingPath(DependencyObject obj, string value)
    {
        obj.SetValue(GridRowBindingPathProperty, value);
    }

    private static void GridBindingPathPropertyChanged(
        DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        var propertyPath = e.NewValue as string;

        if (propertyPath != null)
        {
            var gridProperty =
                e.Property == GridColumnBindingPathProperty
                ? Grid.ColumnProperty
                : Grid.RowProperty;

            BindingOperations.SetBinding(
                obj,
                gridProperty,
                new Binding { Path = new PropertyPath(propertyPath) });
        }
    }
}

您可以像这样在XAML中使用它们:

<ItemsControl.ItemContainerStyle>
    <Style TargetType="ContentPresenter">
        <Setter Property="local:BindingHelper.GridColumnBindingPath" Value="Level"/>
        <Setter Property="local:BindingHelper.GridRowBindingPath" Value="Row"/>
    </Style>
</ItemsControl.ItemContainerStyle>

有关绝对定位(即,绑定Canvas.Leftcanvas.Top属性)的简单解决方法,请参见此答案

2020-05-19