在我的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