在我的WPF应用程序中有一个包含项目的列表框。该列表框通过XAML中的xmldataprovider进行填充,然后将其绑定到列表框的Itemssource属性。以编程方式将命令添加到WPF中的列表框中
那么从XAML,我绑定一个COMAND到ListBox做:
<ListBox.CommandBindings>
<CommandBinding
Command="{x:Static local:mainApp.MyCmd}"
CanExecute="CanExecute"
Executed ="Executed" />
</ListBox.CommandBindings>
,但我不知道如何将一个命令编程绑定到每个ListBoxItem的。怎么做?
在此先感谢。
先抱歉,不要将它作为评论发布。我无法将这一切置于评论中。
好吧,是的我没有使用ICommandSource的Executed和CanExecute属性,尽管我已经在自定义类中注册并实现了它们(在xaml中它们也被注释了)。我在的RoutedCommand规定他们,但不是在自定义类,我已经这样做了窗口的构造函数:
背后的WinMain代码:
public WinMain()
{
InitializeComponent();
// Command binding. If I don't do this Executed and CanExecute are not executed
CommandBindings.Add(new CommandBinding(rcmd,
CommandBinding_Executed, CommandBinding_CanExecute));
}
,然后我实现WinMain函数的代码,这些方法落后太多,因为它:
// ExecutedRoutedEventHandler
private void CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
// Do stuff
}
// CanExecuteRoutedEventHandler
private void CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
// cBgWorkers is a class that check if a background worker is running
e.CanExecute = !cBgWorkers.isRunning;
//if (LayoutListBox != null) LayoutListBox.IsEnabled = !cBgWorkers.isRunning;
}
,并在WinMain函数XAML我调用这样的命令:
<Classes:CommandListBox x:Name="LayoutListBox"
Command="{x:Static local:WinMain.rcmd}"
... >
<...>
</Classes:CommandListBox>
在我的自定义类CommandListBox我有一个CanExecuteChanged中,你可以看到我启用或禁用取决于后台工作是否完成或不控制:
private void CanExecuteChanged(object sender, EventArgs e)
{
this.Enabled = !cBgWorkers.isRunning;
}
但在自定义类我还没有实现您所说的事件处理程序OnSelected。
无法执行它一切正常,自定义控件调用命令和CanExecute方法已达到,并且CanExecute根据后台worker是否完成获取正确的值,true或false,并且自定义控件中的CanExecuteChanged在CanExecute更改其值。当后台工作者启动时,它会被禁用,但是当它完成时它不会被启用。我已经调试过了,当后台工作者完成后,我可以看到CanExecuteChanged被执行,并且this.Enabled获得了正确的值(true),但由于某种原因,在UI中,尽管获得了正确的值,并且尽管在RunWOrkerCompleted(在后台worker)我强制使用CommandManager.InvalidateRequerySuggested()更新UI。
我通过取消注释行解决这个问题:!
如果(!LayoutListBox = NULL)LayoutListBox.IsEnabled = cBgWorkers.isRunning;
in CanExecute方法。我不明白发生了什么事。
然后如果我做你说这是没有必要做到这一点:
CommandBindings.Add(new CommandBinding(rcmd,
CommandBinding_Executed, CommandBinding_CanExecute));
和CommandBinding_Executed & CommandBinding_CanExecute实现。我对吗?
但如果我删除这些方法,我可以在哪里设置this.enabled =!cBgWorkers.isRunning?
我想WPF自动为我的自定义控件设置isEnabled属性。这个怎么做?
在此先感谢。
我正在应用您所说的关于附加行为的文章,并对其进行了一些更改以适应我的ListBox。它运作不好,或者我做错了什么。我想要的是避免ListBox成员(listBoxItems)可以在长期任务(后台工作者)正在运行时选择。所以,我修改文章的方法之一是:
static void OnListBoxItemSelected(object sender, RoutedEventArgs e)
{
// Only react to the Selected event raised by the ListBoxItem
// whose IsSelected property was modified. Ignore all ancestors
// who are merely reporting that a descendant's Selected fired.
if (!Object.ReferenceEquals(sender, e.OriginalSource))
return;
ListBoxItem item = e.OriginalSource as ListBoxItem;
if (item != null)
{
// (*) See comment under
item.IsEnabled = !cBgWorkers.isRunning;
if (!cBgWorkers.isRunning)
{
item.BringIntoView();
}
}
}
(*)cBgWorkers是有一些方法和属性公共静态类。 其中一个属性是isRunning,表示当前没有后台工作人员正在运行。然后,如果没有后台工作人员正在运行,则必须启用列表框成员,否则必须禁用它们,因此当用户单击一个列表框项目时,当前页面不会更改为另一个,因为我之前禁用了它(每个列表框项目都附加了一个页面在我的主要应用程序)。
当其中一个后台工作人员(bw)或全部正在运行时,我选择列表框项目一切正常:列表框项目被禁用,因为有bw正在运行,并且它避免了将当前页面更改为另一个。当然,如果我禁用列表框项目(或列表框项目),我不能再选择它,因为它被禁用,这是我的问题,因为我希望当bw完成在bw运行时已禁用的列表框项目时,他们再次启用。不幸的是,当我看到它的附加行为不是由WPF自动完成的,并且命令具有此优势(由WPF自动控制更新)。那么,如何禁用/重新启用列表框项目时,分别运行或没有分别?
据我所知,附加行为的一个优点是我认为它更有效率,因为它们不是不断地调用行为(只有当行动,例如选择产生时)。命令不断(不经常)检查绑定到控件的动作是否可以执行(所以如果可以执行它们,WPF会自动启用控件,否则它们会显示为禁用),对吗?
谢谢。
这个问题可能会有帮助:http://stackoverflow.com/questions/845446/wpf-mvvm-commands-are-easy-how-to-connect-view-and-viewmodel-with-routedevent – 2010-07-13 16:23:11