为了账号安全,请及时绑定邮箱和手机立即绑定

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

/ 猿问

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

C#
智慧大石 2019-11-19 15:27:26

我在创建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中,我出现了错误。谁能帮我 ?


查看完整描述

2 回答

?
斯蒂芬大帝

想BindingHelper从@clemens 添加我对这个想法的经验。这是一个ListViewItem很好的解决方案,但我发现以a 为目标时,绑定将无法访问基础视图模型。对其进行调试之后,我发现我需要确保绑定是相对于ListViewItem自身及其相关.Content属性的,以使其能够正确链接到项目的视图模型。


我的特殊用例是根据视图模型值设置IsTabStop属性ListViewItem:


private static void BindingPathPropertyChanged(DependencyObject obj,

    DependencyPropertyChangedEventArgs e)

{

    if (e.NewValue is string propertyPath)

    {

        var binding = new Binding

        {  

            Path = new PropertyPath($"Content.{propertyPath}"),

            Mode = BindingMode.OneWay,

            RelativeSource = new RelativeSource

            {

                Mode = RelativeSourceMode.Self

            }

        };

        BindingOperations.SetBinding(obj, Control.IsTabStopProperty, binding);

    }

}

希望这对其他人有帮助的有帮助。


查看完整回答
反对 回复 2019-11-19
?
守候你守候我

如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.Left和canvas.Top属性)的简单解决方法,请参见此答案。


查看完整回答
反对 回复 2019-11-19

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信