2017-08-02 88 views
0

我有一個ListBox控件的情況。項目模板內有一個按鈕。當我點擊按鈕時,我希望選擇所述ListBox的項目以更改爲該按鈕所在的項目。此刻,我可以通過單擊項目模板中的其他位置來更改所選項目,但如果我選擇按鈕。要澄清評論者的最後一句,如果在不是按鈕的項目模板中單擊,SelectedItem將按預期更改。如果您單擊項目模板中的按鈕,SelectedItem不會更改。列表框中的按鈕ItemTemplate沒有選擇項目

更多信息:我正在使用MVVM,並且該按鈕在視圖模型中附加了一條命令。任何解決方案都需要讓這個繼續工作。

ListBox鏈接到ItemSource,並且ListBox的SelectedItem被綁定到視圖模型中的屬性。

如果有一種方法可以做到這一點,我到目前爲止一直無法找到它。

我正在使用C#和Visual Studio 2010.

謝謝。

+1

XAML和CS的位將是很有益的。 *「,如果我選擇按鈕」* - 它不能正常工作? – Sinatr

回答

1

如果您可以使用ToggleButton並將IsChecked綁定到ListBoxItemIsSelected屬性,那麼它會沒事的。
原因是因爲您的ListBoxItem未選中是因爲Button正在處理MouseDown事件,因此使ListBoxItem不知道點擊。在你的按鈕中創建一個Click的事件處理程序並設置e.Handled = false;

+0

對不起,我不明白。你說這兩件事情都是必要的嗎? – TheFaithfulLearner

+0

@ TheFaithfulLearner不用擔心,我的意思是_如果你可以,這意味着如果你不需要使用'Button'。這意味着如果你需要按鈕一旦完成就被「取消點擊」。但是沒有兩件事情都沒有必要。嘗試添加Click事件處理程序,並設置'e.handled = false;' – XAMlMAX

+0

@TheFaithfulLearner還有一件事。當你把事件處理程序放在XAML中時,它在Command Biding之前,因此它將在命令之前執行。 – XAMlMAX

1

你的代碼有點有用,但是這裏有一個虛擬的例子,介紹如何通過MVVM模式在按鈕上單擊來選擇ListBoxItem

public class MyViewModel : BaseViewModel // implements INotifyPropertyChanged 
{ 
    private ICommand _myCommand; 

    public ICommand MyCommand { get {return _myCommand;} private set { _myCommand = value; OnPropertyChanged(); }} 

    private ObservableCollection<int> _myObjects; 

    public ObservableCollection<int> MyObjects { get {return _myObjects;} private set {_myObjects = value; OnPropertyChanged();}} 

    private int _mySelectedObject; 

    public int MySelectedObject { get {return _mySelectedObject;} set {_mySelectedObject = value; OnPropertyChanged(); }} 

    public MyViewModel 
    { 
     MyCommand = new RelayCommand(SetSelectedObject); // the source code for RelayCommand may be found online. 
    } 

    private void SetSelectedObject(object obj) 
    { 
     int myInt = (int)obj; 

     MySelectedObject = myInt; 
    } 
} 

某些XAML零件已被擦除以保持簡單。不要簡單地複製/粘貼此代碼段,將其修改爲您的代碼。

<UserControl x:Name="root" DataContext="{Binding MyViewModel, Source={StaticResource Locator.MyViewModel}}"> 
    <ListBox ItemsSource="{Binding MyObjects}" SelectedItem="{Binding SelectedItem, Mode=TwoWay}"> 
     <ListBox.ItemTemplate> 
      <DataTemplate> 
       <StackPanel> 
        <TextBlock Text="{Binding }"/> 
        <Button Command="{Binding MyCommand, ElementName=root}" CommandParameter="{Binding }"/> 
       </StackPanel> 
      </DataTemplate> 
     </ListBox.ItemTemplate> 
    </ListBox> 
</UserControl> 

我還沒有測試過這段代碼。所以可能會有一些錯誤。不要猶豫,指出這些,我會更新我的代碼。

編輯:這裏是(從Telerik的修改)我RelayCommand實現的源代碼:

public class RelayCommand : ICommand 
{ 
    public event EventHandler CanExecuteChanged 
    { 
     add { CommandManager.RequerySuggested += value; } 
     remove { CommandManager.RequerySuggested -= value; } 
    } 

    private Action<object> _methodToExecute; 
    private Func<object, bool> _canExecuteEvaluator; 

    public RelayCommand(Action<object> methodToExecute, Func<object, bool> canExecuteEvaluator) 
    { 
     _methodToExecute = methodToExecute; 
     _canExecuteEvaluator = canExecuteEvaluator; 
    } 

    public RelayCommand(Action<object> methodToExecute) 
     : this(methodToExecute, null) 
    { 
    } 

    public bool CanExecute(object parameter) 
    { 
     if (_canExecuteEvaluator == null) 
     { 
      return true; 
     } 
     else 
     { 
      bool result = _canExecuteEvaluator.Invoke(parameter); 
      return result; 
     } 
    } 

    public void Execute(object parameter) 
    { 
     _umethodToExecute.Invoke(parameter); 
    } 
} 
+0

你好。感謝您的信息。我開始將這一點付諸實踐,但是當我嘗試使用參數'SetSelectedObject'初始化MyCommand成爲一個新的RelayCommand時。該方法也存在,就像你寫的那樣。給出的錯誤是'參數1:無法從'方法組'轉換爲'System.Action'。我確實使用MVVM Light ...也許這對事物有影響。 – TheFaithfulLearner

+0

如果你想使用我的解決方案,你可能需要使用另一個RelayCommand實現。請參閱我的帖子,我剛剛編輯它。 – Atlasmaybe

相關問題