复选框命令行为Silverlight的MVVM模式 [英] CheckBox Command Behaviors for Silverlight MVVM Pattern

查看:253
本文介绍了复选框命令行为Silverlight的MVVM模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想检测的一个项目被选中,和项中使用Silverlight 4和棱镜框架列表框检查。我发现这个例子的创造行为,并试图跟随它,但没有是发生在调试器。我有三个问题:

I am trying to detect when an item is checked, and which item is checked in a ListBox using Silverlight 4 and the Prism framework. I found this example on creating behaviors, and tried to follow it but nothing is happening in the debugger. I have three questions:

  1. 为什么没有我的命令执行?
  2. 如何确定被检查哪些项目(即传递命令参数)?
  3. 如何调试呢? (即我在哪里可以把破发点,开始踏入这个)

下面是我的code:

查看:

        <ListBox x:Name="MyListBox" ItemsSource="{Binding PanelItems, Mode=TwoWay}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <CheckBox IsChecked="{Binding Enabled}" my:Checked.Command="{Binding Check}"  />
                        <TextBlock x:Name="DisplayName" Text="{Binding DisplayName}"/>
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

视图模型:

public MainPageViewModel()
{
    _panelItems.Add( new PanelItem
    {
        Enabled = true,
        DisplayName = "Test1"
    } );

    Check = new DelegateCommand<object>( itemChecked );
}

public void itemChecked( object o )
{
//do some stuff
}

public DelegateCommand<object> Check { get; set; }

行为类

public class CheckedBehavior : CommandBehaviorBase<CheckBox>
    {
        public CheckedBehavior( CheckBox element )
            : base( element )
        {
            element.Checked +=new RoutedEventHandler(element_Checked);
        }

        void element_Checked( object sender, RoutedEventArgs e )
        {
            base.ExecuteCommand();
        }               
    }

命令类

public static class Checked
{
    public static ICommand GetCommand( DependencyObject obj )
    {
        return (ICommand) obj.GetValue( CommandProperty );
    }

    public static void SetCommand( DependencyObject obj, ICommand value )
    {
        obj.SetValue( CommandProperty, value );
    }

    public static readonly DependencyProperty CommandProperty =
            DependencyProperty.RegisterAttached( "Command", typeof( CheckBox ), typeof( Checked ), new
            PropertyMetadata( OnSetCommandCallback ) );

    public static readonly DependencyProperty CheckedCommandBehaviorProperty =
                DependencyProperty.RegisterAttached( "CheckedCommandBehavior", typeof( CheckedBehavior ), typeof( Checked ), null );

    private static void OnSetCommandCallback( DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e )
    {
        CheckBox element = dependencyObject as CheckBox;
        if( element != null )
        {
            CheckedBehavior behavior = GetOrCreateBehavior( element );
            behavior.Command = e.NewValue as ICommand;
        }
    }
    private static CheckedBehavior GetOrCreateBehavior( CheckBox element )
    {
        CheckedBehavior behavior = element.GetValue( CheckedCommandBehaviorProperty ) as CheckedBehavior;
        if( behavior == null )
        {
            behavior = new CheckedBehavior( element );
            element.SetValue( CheckedCommandBehaviorProperty, behavior );
        }

        return behavior;
    }
    public static CheckedBehavior GetCheckCommandBehavior( DependencyObject obj )
    {
        return (CheckedBehavior) obj.GetValue( CheckedCommandBehaviorProperty );
    }
    public static void SetCheckCommandBehavior( DependencyObject obj, CheckedBehavior value )
    {   
        obj.SetValue( CheckedCommandBehaviorProperty, value );
    }               

}

推荐答案

您的样品是不够的,我的PC上的摄制,但这里是我第一次改正的事情:

Your sample is not enough for a repro on my PC, but here are the things that I'd correct first:

  • 在DataTemplate中的绑定丢失,模式=双向,如果你想将Enabled属性将在您的PanelItem设置 ( - 的的ItemsSource绑定不需要模式=双向,但这是一个小细节)
  • ItemTemplate中的DataContext的是PanelItem实例,所以命令检查的结合似乎是错误的:没有对PanelItem没有入住酒店。的结合应该是: 我:Checked.Command ={结合的ElementName = MyListBox,路径= DataContext.Check}
  • The bindings in the DataTemplate are missing ", Mode=TwoWay" if you want the Enabled property to be set in your PanelItem (- The ItemsSource binding does not need the Mode=TwoWay, but this is a minor detail)
  • The DataContext of the ItemTemplate is the PanelItem instance, so the binding of the Check command seems wrong: there is no Check property on PanelItem. The binding should be: my:Checked.Command="{Binding ElementName=MyListBox, Path=DataContext.Check}

这种东西总是难以调试。看VS的输出窗口;绑定错误(找不到路径)将显示在此处。当你有一个DP的变化回调(如OnSetCommandCallback),断点会告诉你如何绑定去了。

This kind of stuff is always hard to debug. Look at the output window of VS; binding errors (path not found) are displayed there. When you have a DP change callback (like OnSetCommandCallback), a breakpoint there will tell you how the binding went.

编辑:1的评论后增加(因为我不能在电脑上使用的评论功能,我现在使用) 该命令附加属性被定义为经过类类型复选框,但在虚拟机检查属性是一个DelegateCommand。我使用WPF的类型不匹配同意:-) 财产申报是这样的:

added after 1st comment (as I can't use the comment feature on the PC I have to use now) The Command attached property is defined as type CheckBox in the Checked class, but the Check property in the VM is a DelegateCommand. I agree with WPF on the type mismatch :-) The property declaration is like this:

public static readonly DependencyProperty CommandProperty = 
    DependencyProperty.RegisterAttached( 
        "Command", typeof( CheckBox ), 
        typeof( Checked ), new PropertyMetadata( OnSetCommandCallback ) ); 

第二个参数应该是属性类型,所以我想是这样的ICommand你的情况。

The second parameter should be the property type, so I guess something like ICommand in your case.

出于好奇:在OnSetCommandCallback,你不关心设置为Command属性(这是e.NewValue)的值。你如何关联CheckedBehavior的实例,以虚拟机的检查属性?

Out of curiosity: in OnSetCommandCallback, you don't care for the value set to the Command property (which is in e.NewValue). How do you relate an instance of CheckedBehavior to the Check property of the VM ?

第二个意见后编辑: 不,上面的第二个段落是不相关的你的问题。也许它没有任何意义。我想不通CheckedBehavior的作用。

Edit after second comment: No, the 2nd paragraph above is not related to your question. Maybe it does not make sense. I can't figure out the role of CheckedBehavior.

有关问题,其中项目被选中/取消:你有什么需要更多的precisely?你有一个PanelItem的实例,其Enabled属性正在通过招标设置为true或false;所以检查的项目是那些与启用=真。

Concerning the question of which item is checked/unchecked: what do you need more precisely ? You have a PanelItem instance, whose Enabled property is being set to true or false through the biding; so the checked items are the ones with Enabled=true.

3后评论编辑: 感谢您的需要的解释。你不是真正使用的结合的附加属性的路径参数,你可以写:

Edit after 3rd comment: Thanks for the explanation of your needs. You're not really using the path parameter of the binding to the attached property, you could write:

my:Checked.Command="{Binding}"

这样,e.NewValue在OnSetCommandCallback绑定PanelItem。因此,它可以提供给CheckedBehavior实例(在其构造函数),它调用执行的ICommand时可以转发。

This way, e.NewValue is the bound PanelItem in the OnSetCommandCallback. So it could be given to the CheckedBehavior instance (in its constructor), which could forward it when calling Execute of ICommand.

这篇关于复选框命令行为Silverlight的MVVM模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆