UWP与uwp中的FindAncestor等效的功能 [英] UWP equivalent function to FindAncestor in uwp

查看:104
本文介绍了UWP与uwp中的FindAncestor等效的功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个订单列表,当订单状态为已取消时,我想使文本闪烁。到目前为止,我的代码有效。但是,有时会引发异常:

I have a list of orders and when the order status is Cancelled, I want to blink the text. So far, my code works. However, sometimes it will throws exception:


WinRT信息:无法解析TargetName lblOrderStatus

WinRT information: Cannot resolve TargetName lblOrderStatus

由于某种原因可以找到 lblOrderStatus 。因此,我想使用 FindAncestor,但UWP中不存在FindAncestor。 uwp中有与FindAncestor等效的功能吗?

For some reason lblOrderStatus can be found. So, I want to use "FindAncestor", but FindAncestor doesn't exists in UWP. Is there any equivalent function to FindAncestor in uwp?

这是我的代码:

<ItemsControl x:Name="Orders" Grid.Row="1" Background="Transparent">
    ...
    ...
    ...
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Grid>
                ...
                ...
                ...
                <Viewbox Grid.Column="3" StretchDirection="DownOnly" HorizontalAlignment="Right">
                    <TextBlock x:Name="lblOrderStatus" Text="{Binding Path=OrderItemStatus, Mode=OneWay}" FontSize="18">
                        <TextBlock.Resources>
                            <Storyboard x:Name="sbBlinking">
                                <DoubleAnimation Storyboard.TargetProperty="(FrameworkElement.Opacity)"
                                                 Storyboard.TargetName="lblOrderStatus"
                                                 From="1" To="0" AutoReverse="True" Duration="0:0:0.5" RepeatBehavior="Forever" />
                            </Storyboard>
                        </TextBlock.Resources>
                        <interactive:Interaction.Behaviors>
                            <core:DataTriggerBehavior Binding="{Binding OrderItemStatus, Converter={StaticResource EnumToStringConverter}}" ComparisonCondition="Equal" Value="Cancelled">
                                <media:ControlStoryboardAction Storyboard="{StaticResource sbBlinking}" />
                            </core:DataTriggerBehavior>
                        </interactive:Interaction.Behaviors>
                    </TextBlock>
                </Viewbox>
            </Grid>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>


推荐答案

考虑到我所看到的所有解决方案使用 ElementName 绑定是UWP没有RelativeSource AncestorType绑定选项的最简单的解决方法。

Considering all the solutions I've seen, I feel that using ElementName binding is the simplest workaround to UWP not having a RelativeSource AncestorType binding option.

假设您有一个页面及其 DataContext 使用命令 MyCommand 设置为视图模型,并且希望列表中的每个项目在单击按钮时都可以执行:

Assuming you've got a Page with its DataContext set to a viewmodel with a command MyCommand, and you want each item in your list to execute it when its button is clicked:

<Page Name="thisPage">
    ...
    <ListView ...>
        <ListView.ItemTemplate>
            <DataTemplate>
                <Button Command="{Binding ElementName=thisPage, Path=DataContext.MyCommand}" />
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</Page>

此解决方案的最初问题是您无法将DataTemplate提取为要使用的资源它在多个屏幕(甚至对话框)上显示; thisPage 可能在每个地方都不存在,或者不适合将根元素命名为 thisPage。

My initial problem with this solution is that you can't extract the DataTemplate out as a resource to use it on multiple screens (or even dialog boxes); thisPage might not exist in each of those places, or it might not be appropriate to name the root element "thisPage".

但是,如果使用约定,则在每个使用该DataTemplate的屏幕中都包含一个令牌UI元素,并使用一致的名称进行引用,它将起作用。默认情况下,此元素的DataContext将是您的ViewModel(假设您的根元素也是如此)

But if you use a convention where you include a token UI element in every screen that uses that DataTemplate, and refer to it by a consistent name, it will work. By default this element's DataContext will be your ViewModel (assuming your root element does too)

<Rectangle Name="VmDcHelper" Visibility="Collapsed"/> 

...然后在独立资源XAML文件中,您可以这样编写DataTemplate:

...then in your standalone resources XAML file you can write your DataTemplate like this:

<DataTemplate x:Key="MyDataTemplate">
    <Button Command="{Binding ElementName=VmDcHelper, Path=DataContext.MyCommand}" />
</DataTemplate>

然后,在使用该模板资源的每个页面/屏幕/对话框上,只需放入一个副本矩形(或其他任何东西),一切都将在运行时正确绑定

Then, on every page/screen/dialog that you use that template resource, just drop in a copy of that Rectangle (or whatever) and everything will bind correctly at run-time

这显然是一种黑客解决方案,但经过进一步思考,却没有感觉比第一次使用WPF的AncestorType更像是一种黑客(必须确保您的祖先类型在使用DataTemplate的所有位置上始终保持一致)。

This is clearly a hack solution, but after thinking about it some more, it doesn't feel like any more of a hack than using WPF's AncestorType in the first place (having to ensure that your ancestor type is always consistent in all the places you use your DataTemplate).

这篇关于UWP与uwp中的FindAncestor等效的功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆