当我使用caliburn micro时,如何将wpf网格上的按钮绑定到MVVM上的方法

时间:2013-09-24 11:28:18

标签: c# wpf xaml mvvm caliburn.micro

我在wpf窗口上有一个Grid,我想添加一个功能,用户可以通过单击删除按钮删除某些项目。该应用程序使用Calibrun Micro将视图绑定到ViewModel。

我的问题?

1-在WPF中使用按钮从网格中删除项目是个好主意吗?

2-如何将按钮绑定到VM上的方法,并且在methd中获取指向应该删除的项目的指针?

EDIT1

我以这种方式将按钮添加到datagrid:

<DataGridTemplateColumn Width="100">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <Button Content="Delete" cal:Message.Attach="DeleteFromList($dataContext)" />
         </DataTemplate>
     </DataGridTemplateColumn.CellTemplate>
 </DataGridTemplateColumn>

和c#代码如下:

 public void DeleteFromList(object tmp)
    {

    }

但是数据网格上的按钮被禁用,单击它们不会触发DeleteFromList方法(我使用调试器检查过)。

为什么他们被禁用?如何启用它们?

2 个答案:

答案 0 :(得分:9)

这取决于您的按钮的放置方式 - 是否有一个“删除”按钮&#39;按钮或您是否在网格中每行添加了一个按钮(我们是在说DataGrid还是只是Grid?)

假设您正在讨论DataGrid,您可以轻松地向按钮添加操作消息命令,并将正在删除的项目传递给VM上的消息处理程序

e.g。在VM中

public class MyViewModel
{
    public DataItemCollectionTypeName ItemCollection { get; set; }

    public void DeleteItem(DataItemTypeName item)
    {
        ItemCollection.Remove(item);
    }
}

假设ItemCollection绑定到网格,按钮XAML可能如下所示:

<Button cal:Message.Attach="[Click] = [DeleteItem($datacontext)]" />

如果这是一个模板行,您可能还需要设置Action.TargetWithoutContext(它应该绑定到VM),否则CM将无法找到VM来调用

如果您的网格中没有单个按钮,则始终可以定位操作消息中的网格SelectedItem

<DataGrid x:Name="SomeDataGrid"></DataGrid>
<Button cal:Message.Attach="[Click] = [DeleteItem(SomeDataGrid.SelectedItem)]" />

它可能是(也可能是)CM将查看的默认属性,因此除非您修改了默认约定,否则您可能不需要指定属性名称

<DataGrid x:Name="SomeDataGrid"></DataGrid>
<Button cal:Message.Attach="[Click] = [DeleteItem(SomeDataGrid)]" />

修改

澄清一下:为了让CM找到要调用DeleteItem方法的VM,它使用当前项的DataContext。在ItemsControl派生控件的情况下,每个项的datacontext指向绑定的项,而不是ViewModel。

为了给CM提供一个关于它应该尝试解析DeleteItem方法的对象的提示,您可以使用Action.TargetWithoutContext附加属性,该属性为操作消息应用目标对象而不更改绑定行/项的DataContext

您可以使用元素名称语法指向正确的位置:

在此示例中,我使用网格作为根元素并将其命名为LayoutRoot,然后我将动作消息目标指向LayoutRoot.DataContext(这将是ViewModel )使用ElementName语法。您可以使用任何方法(AncestorType或其他)

<Grid x:Name="LayoutRoot">
    <DataGridTemplateColumn Width="100">
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <Button Content="Delete" cal:Message.Attach="DeleteFromList($dataContext)" cal:Action.TargetWithoutContext="{Binding DataContext, ElementName=LayoutRoot}" />
             </DataTemplate>
         </DataGridTemplateColumn.CellTemplate>
     </DataGridTemplateColumn>
</Grid>

那应该有效!

答案 1 :(得分:1)

你可以这样做......

<Button cal:Message.Attach="[Event MouseEnter] = [Action Save($this)]"> 

检查文档,因为他们会解释您需要做什么,并应回答您的问题:link