很久以前,我们就有Snoop这样的工具实时修改、查看正在运行的WPF程序,那时候调个样式,修改个模板,相当滋润。随着历史的车轮陷进WP的泥潭中,无论WP7的Silverlight还是WP8.1的runtime,偶们都不能方便快捷的查看APP的可视化树(Visual Tree)了,呜呼哉,是可忍孰不可忍放下筷子就骂微软。没想到Visual Studio 2015倒是给了我们一个惊喜,自带了一套非常强大的调试工具Live Visual Tree。本篇我们用简单的例子讨论下该工具的使用。
首先我们看以下这段XAML,一个常见的ListView,定义了一个简单的ItemTemplate,希望在ListViewItem被点击时触发Tapped事件。哪里不会点哪里,So easy!
<ListView ItemsSource="{Binding People}"> <ListView.ItemTemplate> <DataTemplate> <Grid Background="LightGray" Tapped="Grid_Tapped"> <TextBlock Text="{Binding}"></TextBlock> </Grid> </DataTemplate> </ListView.ItemTemplate> </ListView>
悲剧总是发生在莫名之间,你发现除了戳Grid设置成LightGray的一块区域有效,其他ListViewItem区域戳了也没什么卵用……于是你很聪明地给Grid添加了HorizontalAlignment="Stretch",然后默念了一句“妈的智障”。
童鞋,怎么可能会有用呢?总不能本篇到此结束吧?
既然没有用,那自然是到我们祭出神器Live Visual Tree一窥究竟的时候了!在Visual Studio 2015中按下F5进入Debug模式,你会发现左侧区域出现了新窗口Live Visual Tree!有点类似于Document Line,不同之处这里列出了运行时的Visual Tree。
如果仅仅用来看结构层次的话,就和Document Outline窗口一样了。这里我们单击最左上角的按钮“Enable selection in the running application”,之后点击运行中ListView的ListViewItem(比如“赵六”),会看到APP中的ListViewItem被红色虚线选中,同时Live Visual Tree会展开到对应元素的位置。
同时也可以在右侧的Live Property Explorer中看到对应元素各项属性的当前值,并且还可以任意修改各个属性的值,同时立即反应到运行中的APP上。
比如我们在选中“赵六”后在右侧Live Property Explorer将ListViewItemPresenter的Content属性改为“王二麻子”看一下:
如果细心察看ListViewItemPresenter下包含的TextBlock,会发现TextBlock对应的Text属性也已被修改成了“王二麻子”。
是不是感觉打开了新世界的大门,要成为海贼王的男人(此处有歧义)……
接下来我们选中ListViewItemPresenter下的Grid,发现虚线红框真的只有灰色那么一小块,无论设不设置HorizontalAlignment="Stretch",但是比较发现无论选中ListViewItemPresenter还是ListViewItem都是横向撑满的,那问题容易解决咯,设置ListViewItem的HorizontalContentAlignment="Stretch"即可。修改后效果如下:
取消选中最左上角的“Enable selection in the running application”,再点击一下王二麻子的右侧部分,发现如愿弹框了。
至此,问题已经定位并且找到了解决方案。我们需要通过ListView的ItemContainerStyle属性修改ListViewItem的样式,设置HorizontalContentAlignment="Stretch"属性。(妄图给ListViewItemPresenter的童鞋会收到以下报错信息:
Cannot apply a Style with TargetType 'Windows.UI.Xaml.Controls.Primitives.ListViewItemPresenter' to an object of type 'Windows.UI.Xaml.Controls.ListViewItem').
修改后的XAML如下:
<ListView ItemsSource="{Binding People}"> <ListView.ItemTemplate> <DataTemplate> <Grid Background="LightGray" Tapped="Grid_Tapped"> <TextBlock Text="{Binding}"></TextBlock> </Grid> </DataTemplate> </ListView.ItemTemplate> <ListView.ItemContainerStyle> <Style TargetType="ListViewItem"> <Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter> </Style> </ListView.ItemContainerStyle> </ListView>
点击有效区域的问题基本得到解决,同时Live Visual Tree的基本操作也已介绍完毕,剩下的还请各位进一步学习研究。
public sealed partial class MainPage : Page { public List<string> People { get; set; } public MainPage() { this.InitializeComponent(); People = new List<string> { "张 三", "李 四", "王 五", "赵 六" }; this.DataContext = this; } private async void Grid_Tapped(object sender, TappedRoutedEventArgs e) { var text = (e.OriginalSource as TextBlock)?.Text; MessageDialog dialog = new MessageDialog(text); await dialog.ShowAsync(); } }
GayHub: