man*_*ans 6 c# wpf xaml mvvm caliburn.micro
我在wpf窗口上有一个Grid,我想添加一个功能,用户可以通过单击删除按钮删除一些项目.该应用程序使用Calibrun Micro将视图绑定到ViewModel.
我的问题?
1-在WPF中使用按钮从网格中删除项目是一个好主意吗?
2-如何将按钮绑定到VM上的方法,并在methd中获取指向应删除的项目的指针?
我以这种方式将按钮添加到datagrid:
<DataGridTemplateColumn Width="100">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Content="Delete" cal:Message.Attach="DeleteFromList($dataContext)" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
Run Code Online (Sandbox Code Playgroud)
和c#代码如下:
public void DeleteFromList(object tmp)
{
}
Run Code Online (Sandbox Code Playgroud)
但是datagrid上的按钮被禁用,单击它们不会触发DeleteFromList方法(我使用调试器检查).
为什么他们被禁用?如何启用它们?
这取决于按钮的放置方式 - 是否有一个'删除'按钮,或者您是否在网格中每行添加了一个按钮(我们正在谈论DataGrid还是只是Grid?)
假设您正在谈论DataGrid,您可以轻松地向按钮添加操作消息命令,并将正在删除的项目传递给VM上的消息处理程序
例如在VM中
public class MyViewModel
{
public DataItemCollectionTypeName ItemCollection { get; set; }
public void DeleteItem(DataItemTypeName item)
{
ItemCollection.Remove(item);
}
}
Run Code Online (Sandbox Code Playgroud)
假设ItemCollection绑定到网格,按钮XAML可能如下所示:
<Button cal:Message.Attach="[Click] = [DeleteItem($datacontext)]" />
Run Code Online (Sandbox Code Playgroud)
Action.TargetWithoutContext如果这是一个模板行,您可能还需要设置(它应该绑定到VM),否则CM将无法找到VM来调用操作消息
如果您有一个未包含在网格中的单个按钮,则始终可以SelectedItem在操作消息中定位网格
<DataGrid x:Name="SomeDataGrid"></DataGrid>
<Button cal:Message.Attach="[Click] = [DeleteItem(SomeDataGrid.SelectedItem)]" />
Run Code Online (Sandbox Code Playgroud)
它可能是(也可能是)CM将查看的默认属性,因此您可能不需要指定属性名称,除非您修改了默认约定
<DataGrid x:Name="SomeDataGrid"></DataGrid>
<Button cal:Message.Attach="[Click] = [DeleteItem(SomeDataGrid)]" />
Run Code Online (Sandbox Code Playgroud)
编辑
为了澄清:为了让CM找到要调用DeleteItem方法的VM,它使用DataContext当前项的.在ItemsControl派生控件的情况下,每个项的datacontext指向绑定的项,而不是ViewModel.
为了给CM提供一个关于它应该尝试解析DeleteItem方法的对象的提示,可以使用Action.TargetWithoutContext附加属性,该属性为操作消息应用目标对象而不更改DataContext绑定的行/项
您可以使用元素名称语法指向正确的位置:
在这个例子中,我使用了一个网格作为根元素并命名它LayoutRoot,然后我LayoutRoot.DataContext使用ElementName语法将动作消息目标指向(它将是ViewModel).你可以使用任何方法(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>
Run Code Online (Sandbox Code Playgroud)
这应该工作!