我正在尝试检测 时检查项目,并使用Silverlight 4和Prism框架在ListBox中检查哪个项目。我found this example关于创建行为,并试图遵循它,但调试器中没有发生任何事情。我有三个问题:
这是我的代码:
查看:
<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 );
}
}
答案 0 :(得分:2)
您的样本不足以在我的电脑上进行复制,但以下是我首先要纠正的事情:
这种东西总是难以调试。看看VS的输出窗口;在那里显示绑定错误(找不到路径)。当你有一个DP更改回调(比如OnSetCommandCallback)时,会有一个断点告诉你绑定是如何进行的。
编辑:在第一条评论后添加(因为我无法使用PC上的评论功能,我现在必须使用) Command附加属性在Checked类中定义为类型CheckBox,但VM中的Check属性是DelegateCommand。我同意WPF关于类型不匹配的问题:-) 财产声明是这样的:
public static readonly DependencyProperty CommandProperty =
DependencyProperty.RegisterAttached(
"Command", typeof( CheckBox ),
typeof( Checked ), new PropertyMetadata( OnSetCommandCallback ) );
第二个参数应该是属性类型,所以我想你的情况就像ICommand一样。
出于好奇:在OnSetCommandCallback中,您不关心为Command属性设置的值(在e.NewValue中)。如何将CheckedBehavior的实例与VM的Check属性相关联?
第二次评论后编辑: 不,上面的第2段与您的问题无关。也许这没有意义。我无法弄清楚CheckedBehavior的作用。
关于选中/取消选中哪个项目的问题:您更准确地需要什么?您有一个PanelItem实例,其Enabled属性通过biding设置为true或false;所以选中的项目是Enabled = true。
第3次评论后编辑: 感谢您解释您的需求。你并没有真正使用绑定到附加属性的path参数,你可以写:
my:Checked.Command="{Binding}"
这样,e.NewValue就是OnSetCommandCallback中绑定的PanelItem。所以它可以被赋予CheckedBehavior实例(在它的构造函数中),它可以在调用ICommand的Execute时转发它。
答案 1 :(得分:0)
CheckBehavior.cs:
public class CheckBehavior : CommandBehaviorBase<CheckBox>
{
public CheckBehavior(CheckBox element) : base(element)
{
element.Checked += OnElementChecked;
element.Unchecked += OnElementChecked;
}
private void OnElementChecked(object sender, RoutedEventArgs e)
{
if (sender is CheckBox && ((CheckBox)sender).IsPressed)
{
base.ExecuteCommand();
}
}
}
CheckCommand.cs:
public class CheckCommand
{
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 object GetCommandParameter(DependencyObject obj)
{
return obj.GetValue(CommandParameterProperty);
}
public static void SetCommandParameter(DependencyObject obj, object value)
{
obj.SetValue(CommandParameterProperty, value);
}
public static readonly DependencyProperty CommandProperty =
DependencyProperty.RegisterAttached("Command", typeof(ICommand), typeof(CheckCommand), new PropertyMetadata(OnSetCommandCallback));
public static readonly DependencyProperty CommandParameterProperty =
DependencyProperty.RegisterAttached("CommandParameter", typeof(object), typeof(CheckCommand), new PropertyMetadata(OnSetCommandParameterCallback));
public static readonly DependencyProperty CheckedCommandBehaviorProperty =
DependencyProperty.RegisterAttached("CheckedCommandBehavior", typeof(CheckBehavior), typeof(CheckCommand), null);
private static void OnSetCommandCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
CheckBox element = dependencyObject as CheckBox;
if (element != null)
{
CheckBehavior behavior = GetOrCreateBehavior(element);
behavior.Command = e.NewValue as ICommand;
}
}
private static void OnSetCommandParameterCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
CheckBox element = dependencyObject as CheckBox;
if (element != null)
{
CheckBehavior behavior = GetOrCreateBehavior(element);
behavior.CommandParameter = e.NewValue;
}
}
private static CheckBehavior GetOrCreateBehavior(CheckBox element)
{
CheckBehavior behavior = element.GetValue(CheckedCommandBehaviorProperty) as CheckBehavior;
if (behavior == null)
{
behavior = new CheckBehavior(element);
element.SetValue(CheckedCommandBehaviorProperty, behavior);
}
return behavior;
}
public static CheckBehavior GetCheckCommandBehavior(DependencyObject obj)
{
return (CheckBehavior)obj.GetValue(CheckedCommandBehaviorProperty);
}
public static void SetCheckCommandBehavior(DependencyObject obj, CheckBehavior value)
{
obj.SetValue(CheckedCommandBehaviorProperty, value);
}
}
例如:
<CheckBox Commands:CheckCommand.Command="{Binding MyCheckCommand}}"
Commands:CheckCommand.CommandParameter="{Binding}"/>