2017-08-02 59 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

相关问题