XAML: 在 MVVM 模式中,关于绑定的几处技巧

摘要:
GridHolding=“Grid_Holding”>Uid=“MenuItem_Edit”Command=“{BindingEditCategoryCommand}”CommandParameter=“{Binding}”/>

    以下会提到三个绑定的技巧,分别是

  • 在 ListView 中为 ListViewItem 的 MenuFlyout 绑定 Command;
  • 在 ListView 的 事件中绑定所选择项目,即其 SelectedItem属性;
  • 处理文本控件与数值属性绑定中默认值0的问题;

一、在 ListView 中为列表项的 MenuFlyout 绑定 Command;

    当我们为 ListView 编写了 DataTemplate,并在其中加入了 MenuFlyout 时,而且 MenuFlyoutItem 需要绑定 ViewModel 中的 XXXCommand 属性,代码类似如下:

    <Page.Resources>
        <DataTemplate x:Key="CategoryItemTemplate">
            <Grid Holding="Grid_Holding">
                <FlyoutBase.AttachedFlyout>
                    <MenuFlyout>
                        <MenuFlyoutItem x:Uid="MenuItem_Edit" Command="{Binding EditCategoryCommand}" CommandParameter="{Binding}"/>
                        <MenuFlyoutItem x:Uid="MenuItem_Delete" Command="{Binding DeleteCategoryCommand}" CommandParameter="{Binding}"/>
                    </MenuFlyout>
                </FlyoutBase.AttachedFlyout>
                <TextBlock Text="{Binding Name}" FontSize="24" Margin="0,5" />
            </Grid>
        </DataTemplate>
    </Page.Resources>

   这时,如果运行,你会发现,点击 MenuFlyoutItem 时,并不会触发相应的方法,也就是说这样的绑定是无效的;一个可取的解决方案是,将 ViewModel 作为资源放到 XAML 中,然后,更改 Command 的值为:

Command="{Binding EditCategoryCommand,Source={StaticResource viewModelName}}"

   这样可以解决问题,但存在两个问题:1, 这个 viewModel 是一个新创建的对象,而与你实际使用的 ViewModel 对象不是一个,所以;2, ViewModel 必须有无参数的构造函数(其实这与第一个问题是相关联的)。

   在网上查了一些资料之后,终于找到一个较完美的解决方案,如下:修改 Command 的值为:

Command="{Binding DataContext.EditCategoryCommand,ElementName=pageCategory}"

   其中,pageCategory 是 Page 的 x:Name 值;这样 MenuFlyoutItem 就可以正确响应你的操作了。至于修改之后的 Command 的属性值,相信你一看就明白,在此不再赘述。

二、在 ListView 的 事件中绑定所选择项目,即其 SelectedItem属性

   先看代码,注意粗体部分:

            <ListView x:Name="listCategory" ItemsSource="{Binding Categories}" ItemContainerStyle="{StaticResource StretchListViewItemStyle}">
                <Interactivity:Interaction.Behaviors>
                    <Core:EventTriggerBehavior EventName="SelectionChanged">
                        <Core:InvokeCommandAction Command="{Binding CategorySelectedCommand}" CommandParameter="{Binding ElementName=listCategory,Path=SelectedItem}" />
                    </Core:EventTriggerBehavior>
                </Interactivity:Interaction.Behaviors>
                ...

   这个其实很简单,之所以记下来,是因为我原先走了一点弯路,之前没有写 Path,然后到 Command 所指向的方法中,把 parameter 再转 ListView 对象,再获取它的 SelectedItem 属性;现在看来,的确是多走了一段弯路;究其原因,实在是因为自己对 WPF 中绑定还不够熟悉。

三、处理文本控件与数值属性绑定中默认值 0 的问题

   当把文本框的 Text 属性绑定到一个数值属性时,如果该数值属性没有赋值,那么,运行时,它的默认值 0 会显示到文本框中,如果不希望显示默认值 0,则可以使用一个 Converter 来解决,代码如下:

    public class PriceCheckConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, string language)
        {
            float result = (float)value;
            if (result <= 0)
            {
                return string.Empty;
            }
            else
            {
                return result.ToString();
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, string language)
        {
            return value;
        }
    }

   而在绑定中,则直接指定该 Converter 即可,代码如下:

Text="{Binding Bill.Price,Mode=TwoWay,Converter={StaticResource PriceCheckConverter}}"

   如果你有更好的方法,请回复。

参考资料:

Windows 8.1 Command Binding in a DataTemplate

How to implement a navigation button in shared application resources?

(以上两个链接均是针对第一个问题)

免责声明:文章转载自《XAML: 在 MVVM 模式中,关于绑定的几处技巧》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇octave中的一些基本操作分享8个非常时髦的翻页特效(附代码片段)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Notice: Undefined offset 的解决方法

Notice: Undefined offset: 1 in D:wwwrootwraskseo404.php on line 5 Notice: Undefined offset: 2 in D:wwwrootwraskseo404.php on line 5 Notice: Undefined offset: 2 in D:wwwrootwraskse...

Android color颜色-色号总结

code时经常会用到颜色,然而对于像我这样的对于颜色不是很敏感的同学来说,就很痛苦了。 我想要某种颜色,但是又说不出来具体是哪种;这边总结了一下color种类以及色号。 <?xml version="1.0" encoding="utf-8"?> <resources> <color name="white"...

进阶篇-用户界面:6.android studio使用github开源库实现下拉刷新

      说实话,这是我第一次这么正儿八经的用github开源库,之前一直在听一些大神对这个世界级的开源库赞不绝口,今天终于体会到了。由于下拉刷新的类库是在eclipse下开发完成的,而eclipse如何使用如果导入网上的教程都非常详细。昨天我试了半天发现由于自己对android studio还不是很熟悉,所以引用类库的时候发现无从下手。但是今天早晨起来...

sublime text3 搭建c++/c环境

sublime搭建的c++/c使用很方便,实用性很强,自己阅览了无数的博客,csdn,博客园的都看了,最后还是自己摸索着搭建成功了,如果觉得还不错请给个评论谢谢。(提前声明本人专利不允许转载!!!!) 转载备注地址:https://www.cnblogs.com/luhongkai/p/9812851.html 一、配置环境 大部分都是下载安装MinGW文...

关于 SetProcessWorkingSetSize 和内存释放

在应用程序中,往往为了释放内存等,使用一些函数,其实,对于内存操作函数要谨慎使用,比如大家常常想到的 SetProcessWorkingSetSize,其实对于windows来说,系统会自动在程序闲置时(如程序被最小化)释放内存的,自己用内存释放 时,往往会造成一些莫名的内存错误,造成自己的应用程序及系统不稳定。 具体原理有人已经写得很清楚了,以下为转帖的...

C++的关键字 explicit的作用———菜鸟级日记

 C++的关键字 explicit的作用———菜鸟级日记  author:stonehat 从C++大学教程中学到了一个比较好玩的东西。 请看下面代码: #include <stdio.h>class T{public:int a; T() { } T(int a) {this->a = a; }voi...