C#:WPF MVVM 中的按钮绑定

Posted

技术标签:

【中文标题】C#:WPF MVVM 中的按钮绑定【英文标题】:C#: Button binding in WPF MVVM 【发布时间】:2017-06-28 14:09:14 【问题描述】:

所以我有一个绑定到某个 ObservableCollection 的 ItemsControl 视图。在 DataTemplate 我需要两个按钮。当我尝试将这些按钮绑定到我定义它们的位置并启动应用程序时,单击按钮时没有任何反应。

观点:

<UserControl x:Class="GraphicalUserInterface.Views._2_ToDoList.ToDoListMainView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local="clr-namespace:GraphicalUserInterface.Views._2_ToDoList"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="600"
         DataContext="Binding Source=StaticResource Locator, Path=ToDoListMain">
<Grid>
    <ItemsControl Margin="5" ItemsSource="Binding ListEntries">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Border CornerRadius="5" BorderThickness="2" BorderBrush="Black" Height="50" Margin="5">
                    <StackPanel Orientation="Horizontal" Margin="0,5">
                        <Label FontWeight="Bold">Customer:</Label>
                        <Label Content="Binding Customer" Margin="0,0,20,0"/>
                        <Label FontWeight="Bold">Trainer:</Label>
                        <Label Content="Binding Trainer" Margin="0,0,20,0"/>
                        <Label FontWeight="Bold">Date:</Label>
                        <Label Content="Binding Date" Margin="0,0,20,0"/>
                        <Label FontWeight="Bold">RequestType:</Label>
                        <Label Content="Binding RequestType" Margin="0,0,20,0"/>
                        <Button Margin="5" Width="100" CommandParameter="Binding" Command="Binding Path=DataContext.ContactBtnClickCommand, RelativeSource= RelativeSource FindAncestor,AncestorType=x:Type ItemsControl">Contact</Button>
                        <Button Margin="5" Width="100" CommandParameter="Binding" Command="Binding DataContext.AcceptBtnClickCommand, RelativeSource=RelativeSource FindAncestor, AncestorType=x:Type ItemsControl">Accept</Button>
                    </StackPanel>
                </Border>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Grid>

班级:

public class ToDoListMainVM : ViewModelBase

    private ObservableCollection<ToDoVM> listEntries;
    public ObservableCollection<ToDoVM> ListEntries
    
        get  return listEntries; 
        set
        
            listEntries = value;
            RaisePropertyChanged();
        
    

    SelectHandler selectHandler = new SelectHandler();
    InsertHandler insertHandler = new InsertHandler();
    DeleteHandler deleteHandler = new DeleteHandler();

    NavigationService navService = new NavigationService();

    public RelayCommand<ToDoVM> AcceptBtnClickCommand;
    public RelayCommand<ToDoVM> ContactBtnClickCommand;

    public ToDoListMainVM()
    
        UpdateToDoList();

        AcceptBtnClickCommand = new RelayCommand<ToDoVM>((p) =>
        
            //Enter into database
            insertHandler.InsertAppointmentToDatabase(new AppointmentVM()
            
                Customer = p.Customer,
                Date = p.Date,
                Trainer = p.Trainer
            );
            //Make it instantly visible in the Calender
            Messenger.Default.Send<NewAppointmentMessage>(new NewAppointmentMessage(p.Customer, p.Date));

            //Delete from ToDo (View)
            ListEntries.Remove(p);

            //Delete from Db
            deleteHandler.DeleteToDo(p);

            //Set view to Calender
            navService.NavigateTo("MyTrainingsMain");

        );

查看模型:

public class ToDoVM

    public int ToDoVMID  get; set; 
    public string RequestType  get; set; 
    public DateTime Date  get; set; 
    public CustomerVM Customer  get; set; 
    public TrainerVM Trainer  get; set; 

【问题讨论】:

尝试将 AncestorType 更改为 UserControl。 ItemsControl 数据上下文是 ListEntries,它不包含命令。您需要将链向上引用到包含命令的上下文。 @EdPlunkett,我只是仔细看了看,打算删除评论 【参考方案1】:

命令属性需要是properties,带有getter。您不能绑定到字段。

    public RelayCommand<ToDoVM> AcceptBtnClickCommand  get; private set; 
    public RelayCommand<ToDoVM> ContactBtnClickCommand   get; private set; 

您的代码的其余部分都很好。绑定是正确的。您可以稍微简化它们,但它们完全按照您编写它们的方式工作。

Command="Binding DataContext.ContactBtnClickCommand, RelativeSource=RelativeSource AncestorType=x:Type ItemsControl"

【讨论】:

以上是关于C#:WPF MVVM 中的按钮绑定的主要内容,如果未能解决你的问题,请参考以下文章

wpf中mvvm的Command绑定后,如何在点击按钮的时候在viewmodel里面异步执行方法。

WPF + MVVM + RadioButton:使用单个属性处理绑定

按钮上的绑定命令不起作用wpf mvvm

2019-11-29-WPF-绑定命令在-MVVM-的-CanExecute-和-Execute-在按钮点击都没触发可能的原因...

WPF MVVM - 带文本框的简单绑定按钮(Icommand)

WPF:如何使用 MVVM 将命令绑定到 ListBoxItem?