在MVVM架构下实现将基于ListViewBase控件的显示项滚动到可视范围内(Windows 8.1)

当我们在开发Windows Store应用的时候,一个常见的场景是,你需要在两个页面之间相互跳转,一个是项目列表页面,一个是详细信息页面。当你点击项目列表页面的某一个项目时,就会跳转到相应的详细信息页面,然后通过回退按钮,你就可以回到原来的项目列表页面。当项目列表的内容很多的时候,回退按钮就会把你带到第一个项目对应的视图上,这当然不是我们希望的,我们希望当页面会退的时候,项目列表页面还是能够显示刚才点击的那个项目。 这个问题很容易解决,Windows Store应用提供了两个API来实现这个功能:ScrollIntoView和MakeVisible。当基于LivstViewBase的控件,比如ListView, GridView单独使用的时候,那么就使用ScrollIntoView这个函数。如果基于ListViewBase的控件作为一个视图放在SemanticZoom控件中的时候,那么就使用MakeVisible函数。但是,这两个函数不是在什么时候调用都能够生效的,必须要等ListViewBase控件已经完成了布局以后才能够调用生效。在这里,比较保险的做法是在Page.Loaded事件处理函数中调用ScrollIntoView;在ListviewBase.Loaded事件处理函数中调用MakeVisible。这样的话,我们就需要将这些调用放在xaml的后台代码中,对于一个遵循MVVM设计模式的程序,这是需要尽量避免的。所以,这里我决定实现一个Behavior来完成将显示项滚动到可视范围内这个功能。 Behavior是Windows 8.1新支持的功能,为了实现Behavior,你需要定义一个实现了IBehavior接口的类,这个接口要求我们实现一个属性和两个函数: public interface IBehavior {     DependencyObject AssociatedObject { get; }     void Attach(DependencyObject associatedObject);     void Detach(); } AssociateObject属性很容易实现,它的值可以通过Attach函数得到,我们只需要实现标准的属性代码就可以了: private DependencyObject _associatedObject;         public DependencyObject AssociatedObject         {             get             {                 return _associatedObject;             }         } 为了实现Behavior的功能,这里我也定义了一个依赖属性LastFocusedItem,它用来设置最后得到焦点的那项,也就是我们需要滚动到显示范围内的那一项: private static readonly DependencyProperty LastFocusedItemProperty = DependencyProperty.Register(“LastFocusedItem”, typeof(object),…

0

Scroll into View for ListViewBase controls when using MVVM in Windows 8.1 Store apps

When you implement a windows store app which can navigate between the item list page and the item detail page, you may hope that the view can go to the last focused item when the page navigates from the item detail page to the item list page. Thus the end users don’t need to scroll the view…

1

一个由不合理布局导致Windows 8.1 store应用失去响应的例子

         如果我们忽视了Windows store应用的界面设计,通常你会得到一个糟糕的用户界面,然而你有没有想过在某种情况下却会导致应用程序失去响应甚至闪退,这里就有这样一个活生生的例子。          这个例子首先要从Windows 8 store应用的应用视图(application view)说起,Windows 8 Store应用有三种视图状态:full screen(程序填满整个屏幕), snapped(应用程序只占据了整个屏幕的一小部分),Fill(应用程序占据了snapped宽度剩余的区域)。所以在windows 8上设计Windows Store应用时,开发者通常会设计三种布局对应于这三种不同的视图。但是在Windows 8.1上取消了这三种视图状态,取而代之的是,应用商店程序可以在一定范围内任意调节应用的宽度,这个范围指的是应用程序有一个最小宽度设定,这通常是500个像素,您的Windows store应用至少要达到这个宽度,或者剩下空间至少有这个宽度。这样就给开发人员带来了挑战,我们不可能使用固定的布局,而是需要不同的宽度动态调整。如果不作调整的话,那么就有可能会发生下面这个问题。         为了重现这个问题,我们可以在Visual Studio  2013上创建一个基于Hub应用模板的Windows store应用,然后在ItemPage添加如下XAML代码: <Grid Grid.Row=”1″ x:Name=”contentRegion”> <Grid.ColumnDefinitions>      <ColumnDefinition x:Name=”firstColumn” Width=”600″/>      <ColumnDefinition x:Name=”secondColumn” Width=”*”/> </Grid.ColumnDefinitions>      <ScrollViewer Grid.Column=”1″ >           <TextBlock Margin=”40″ Text=”{Binding Content}” Style=”{StaticResource BaseTextBlockStyle}” />      </ScrollViewer> </Grid>         当你点击HubPage页面的项目时,应用就会跳转到ItemPage页面。在这个ItemPage页面会显示相应的文字。在全屏状态下,应用工作得很好很流畅。可是,如果你把应用的宽度调整到很小,比如500个像素,这时显示ItemPage页面时就会长时间失去响应,在一些极端的情况下甚至会应为失去响应时间过长而闪退。          实际上这个问题是由于Grid的第二列宽度太小而导致的。在这个页面里,你已经设置了第一个列的宽度为600,而出问题的时候应用的总宽度也不过500,这样留给第二列中的ScrollView里的TextBlock的宽度几乎就没有了。而在第二列中的这个TextBlock通常会有以下属性设置:            …

0

Improper UI layout cause windows store app busy hang in Windows 8.1

  Windows 8 store applications only need to maintain three application views: Full screen mode, snapped mode and filled mode. So the developers generally prepare three sets of UI layout. But in Windows 8.1, you can change the application width freely only if it’s large than the minimum width which is generally 500. It may…

0