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

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

  • 在 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}}"

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

时间: 2024-10-27 08:58:48

WinRT 开发:在 MVVM 模式中,关于绑定的几处技巧的相关文章

WPF ContextMenu 在MVVM模式中无法绑定 Command的解决办法

ContextMenu无论定义在.cs或.xaml文件中,都不继承父级的DataContext,所以如果要绑定父级的DataContext,直接DataContext=“{Binding}”是行不通的 不能绑父级,但是能绑资源 第一步:定义一个中间类用来做资源对象 1 public class BindingProxy : Freezable 2 { 3 #region Overrides of Freezable 4 5 protected override Freezable CreateI

在MVVM模式中,按钮Click事件的绑定方法

原文:在MVVM模式中,按钮Click事件的绑定方法 在MVVM模式中,我们将Button的方法写到ViewModel中,然后绑定到前端界面.通常的做法是写一个类,继承ICommand接口,然而如果按钮比较多的话,就需要写很多的类,对于后期维护造成很大的不变,微软提供了一个DelegateCommand类,可以简化开发. 使用方法如下: 首先生命ViewModel属性,GetMsg函数, public DelegateCommand GetMsg { get { return new Deleg

“Win10 UAP 开发系列”之 在MVVM模式中控制ListView滚动位置

这个扩展属性从WP8.1就开始用了,主要是为了解决MVVM模式中无法直接控制ListView滚动位置的问题.比如在VM中刷新了数据,需要将View中的ListView滚动到顶部,ListView只有一个ScrollIntoView()方法可以控制滚动的位置,但最好在VM中不要出现直接控制View的代码,需要通过其他的方式. 使用一个扩展属性即可实现: /// <summary> /// 将ListView滚动到顶部 使用方法:在ListView增加扩展属性 /// ext:ListViewSc

实战基础技能(08)--------MVVM模式中WPF数据的完全绑定

一:截图,描述:将后台代码的姓名.年龄绑定到文本框,单击”增加年龄“--年龄自+1,单击”显示年龄“--弹出年龄的显示对话框,实现了从文本框修改年龄和后台更改年龄并显示到文本框 运行结果和解决方案管理截图如下: 二:person类 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ComponentModel; namespace 完全数据绑定 {

WPF ContextMenu 在MVVM模式中绑定 Command及使用CommandParameter传参

原文:WPF ContextMenu 在MVVM模式中绑定 Command及使用CommandParameter传参 ContextMenu无论定义在.cs或.xaml文件中,都不继承父级的DataContext,所以如果要绑定父级的DataContext,直接DataContext=“{Binding}”是行不通的 不能绑父级,但是能绑资源 第一步:定义一个中间类用来做资源对象 1 public class BindingProxy : Freezable 2 { 3 #region Over

WPF MVVM模式中,通过命令实现窗体拖动、跳转以及显隐控制

在WPF中使用MVVM模式,可以让我们的程序实现界面与功能的分离,方便开发,易于维护.但是,很多初学者会在使用MVVM的过程中遇到一个显而易见且无法回避的问题,那就是不同的窗体之间如何跳转?很多人在介绍MVVM的使用时,都没有明显提到该如何解决这一问题,不知是因为觉得太简单了还是其他原因. 博主根据自己的开发经验,写了一个简单的示例程序,介绍MVVM模式中,如何通过命令来控制窗体的跳转.拖动与显隐控制. 先看效果: 主窗体中只有一个按钮,点击该按钮后,可以打开新的窗. 新窗体可以为自定义样式窗体

uwp开发:MVVM模式和数据绑定结合使用实战示例

——我的<简影uwp>开发了一段时间了,现在各个板块和基本功能已经完工,剩下的就是细节方面的处理和UI排版设计了.开发期间遇到过很多问题,由于是个人独立开发.所以好多问题需要自己想好长时间,或者去网上寻找大神求助,有时候晚上做梦都是满脑子的代码.好的是大部分最终都解决了!真的非常感谢那些帮助我的大神们,和他们交流,我学到了很多... 好了,闲话不多说,前几天,我处理的是集合数据绑定的问题,也就是说返回的是一个集合数据,用MVVM模式来说,让ViewModel层实现ObservableColle

Messenger在MVVM模式中的应用

Messenger在MVVM模式中的应用 Messenger在MVVM中应用的前提 我们知道在MVVM架构中,系统平台的Silverlight客户端界面开发和业务逻辑已经被分开,XAML是SL的主要部分,界面设计者只需要绑定ViewModel里的数据即可.但是在ViewModel里有些时候是需要界面发出响应的,在这种情况下,Messenger显示出它的用处. Messenger的架构 Messager构件代码 定义Imessager接口 注册一个接收消息的类型,比如某一控件来接收消息 void

silverlighter下MVVM模式中利用Behavior和TargetedTriggerAction实现文本框的一些特效

在silverlight一般开发模式中,给文本框添加一些事件是轻而易举的,然而MVVM开发模式中,想要给文本框添加一些事件并非那么容易,因为MVVM模式中,只有ICommand接口,而且也只有Button中才有Command属性,通过ViewModel可以将方法绑定到Button上面,却无法绑定到文本框和其他一些控件.. Behavior的出现解决了这一难题,下面就来说一下具体的实现方法: 实例一:在用户登录窗口,用户点击Reset按钮后,让用户名输入框自动获取焦点. 首先要先将ViewMode

JavaScript大杂烩18 - Web开发的MVVM模式

MVC VS. MVP VS. MVVM  了解MVVM模式之前,我们先来简单了解一下从MVC到MVVM的变迁.这个变迁是耦合从紧到松的变迁,是对依赖处理的进化,是应对变化技术的成熟. MVC  MVC全名是Model View Controller, 是模型(model)-视图(view)-控制器(controller)的缩写,它用一种将业务逻辑.数据.界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑.将系统进行MVC分层