zoukankan      html  css  js  c++  java
  • 在WindowsPhone8中生成基于MVVM Light的LongListSelector导航事件bug修改

    在《在WindowsPhone8中生成基于MVVM Light的LongListSelector导航事件》一文中,我们对LongListSelector绑定了相应命令、消息和数据,在运行程序时,发现一个问题:

    我们的命令绑定在了LongListSelector中,用来处理导航事件,这在一般情况下,即绑定的控件不为LongListSelector时,是非常完美的。但是对于LongListSelector,它还存在一个GroupHeader,即A\B\C\D.....这个标题,好,根据上个APP点击这些标题,杯具,bug:

    1.如果进入APP直接点击LongListSelector的GroupHeader,那么直接报空引用异常,因为它并不包含一个实例.Name的属性,无法传参、导航。

    2.如果进入APP点击LongListSelector的某一项,再点击GroupHeader,好吧..会发生蛋疼的效果,GroupHeader会闪现一下选择拼音的页面,然后直接执行页面导航,导航的页面为我们上一次进入的某项的页。

    如何解决呢?折腾了半天,想到了一个方法:把EventToCommand写到TextBlock中而不是LongListSelector中:

    <phone:LongListSelector
                       x:Name="MountainIndexLLS"
                       JumpListStyle="{StaticResource AddrBookJumpListStyle}"
                       Background="Transparent"
                       GroupHeaderTemplate="{StaticResource AddrBookGroupHeaderTemplate}"        
                       LayoutMode="List"
                       IsGroupingEnabled="true"
                       HideEmptyGroups ="true" ItemsSource="{Binding DataSource}">
                        <phone:LongListSelector.ItemTemplate>
                            <DataTemplate>
                                <StackPanel VerticalAlignment="Top">
                                    <TextBlock FontWeight="Bold"  Text="{Binding Name}" Style="{StaticResource PhoneTextLargeStyle}" FontFamily="{StaticResource PhoneFontFamilySemiBold}" Foreground="White" >
                                        <i:Interaction.Triggers>
                                            <i:EventTrigger EventName="Tap">
                                                <cmd:EventToCommand Command="{Binding TapCommand}" CommandParameter="{Binding SelectedItem,ElementName=MountainIndexLLS}"/>
                                            </i:EventTrigger>
                                        </i:Interaction.Triggers>
                                    </TextBlock>
                                    <TextBlock Text="{Binding Region}" Style="{StaticResource PhoneTextNormalStyle}" TextWrapping="Wrap" FontFamily="{StaticResource PhoneFontFamilySemiBold}" Foreground="Gray"/>
                                </StackPanel>
                            </DataTemplate>  
                        </phone:LongListSelector.ItemTemplate>
                    </phone:LongListSelector>
    

     恭喜,如果完全复制这段代码,再一次陷入无解状态,命令无法执行,百度一下:DataTemplate Command,就知道有多少人碰到这个问题:DataTemplate中无法访问到DataContext,因此绑定不会出现任何效果。怎么解决呢?

    我们需要精确这个绑定的位置,修改〈cmd:...>这段代码如下:

    <i:EventTrigger EventName="Tap">
                                                <cmd:EventToCommand Command="{Binding Source={StaticResource Locator},Path=Main.TapCommand}" CommandParameter="{Binding}"/>
                                            </i:EventTrigger>
    

     OK,可以成功绑定,只不过我们现在处理导航的事件放在了TextBlock中(下图中的山峰名),而不是LongListSelector中,这样,LLS得GroupHeader就不会受到TapCommand的影响了。效果如下:

    (上图中,点击LLS的GroupHeader,便不会执行导航命令,因为我们把TapCommand单独绑定在了TextBlock上)

    导航成功,第二款APP的框架终于完成,MVVM改造的好辛苦...

    对于MVVM,查了很多资料。有一位同学的疑问也是我的疑问:

    http://www.cnblogs.com/icuit/archive/2012/05/11/2495396.html

    他这样说:我的疑问在此,原来的思路是将NavigationContext获取到的信息绑定到B页面的某个控件中,并通过B页面的某个带参数的command事件将获取到的信息传递给到B页面的viewModel中并绑定B页面的某个方法中更新B页面的UI。 后来朋友告诉我直接用红色的语句实现,我总觉得这样看起来有点怪怪的,这样有破坏mvvm的原则么? 忘了在哪里看过有文章说尽量不在code-behind中写逻辑?可我觉得有时候不用code-behind会太憋屈。 请大家一起讨论一下关于mvvm中的消息模式应该如何考虑。

    第二个页面的Code-Behind里放更新UI的代码,这到底是否符合MVVM-Light的本质,我也不是很清晰,希望在以后的学习工作中能更透彻的认识MVVM。

  • 相关阅读:
    log4j1修改DailyRollingFileAppender支持日志最大数量
    log4j1 修改FileAppender解决当天的文件没有日期后缀
    log4j生成有日期的日志文件名
    Java删除List和Set集合中元素
    Java并发编程:并发容器之ConcurrentHashMap
    Java并发编程:并发容器之CopyOnWriteArrayList
    java.util.ConcurrentModificationException解决详解
    Handshake failed due to invalid Upgrade header: null 解决方案
    web项目Log4j日志输出路径配置问题
    log4j.properties 的使用详解
  • 原文地址:https://www.cnblogs.com/valentineisme/p/3089722.html
Copyright © 2011-2022 走看看