我遇到了WPF和命令的问题,这些问题绑定到ItemsControl的DataTemplate中的Button.这种情况很简单.ItemsControl绑定到一个对象列表,我希望能够通过单击一个Button删除列表中的每个对象.Button执行命令,Command负责删除.CommandParameter绑定到我要删除的Object.这样我知道用户点击了什么.用户应该只能删除他们的"自己的"对象 - 所以我需要在Command的"CanExecute"调用中进行一些检查,以验证用户是否具有正确的权限.
问题是传递给CanExecute的参数在第一次被调用时是NULL - 所以我无法运行逻辑来启用/禁用命令.但是,如果我启用了allways,然后单击按钮执行命令,则会正确传入CommandParameter.这意味着对CommandParameter的绑定正在起作用.
ItemsControl和DataTemplate的XAML如下所示:
<ItemsControl
x:Name="commentsList"
ItemsSource="{Binding Path=SharedDataItemPM.Comments}"
Width="Auto" Height="Auto">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Button
Content="Delete"
FontSize="10"
Command="{Binding Path=DataContext.DeleteCommentCommand, ElementName=commentsList}"
CommandParameter="{Binding}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Run Code Online (Sandbox Code Playgroud)
所以你可以看到我有一个评论对象列表.我希望将DeleteCommentCommand的CommandParameter绑定到Command对象.
所以我想我的问题是:以前有没有人遇到过这个问题?我的命令会调用CanExecute,但第一次参数总是为NULL - 为什么会这样?
更新:我能够将问题缩小一点.我添加了一个空的Debug ValueConverter,以便在CommandParameter是数据绑定时输出消息.事实证明,在CommandParameter绑定到按钮之前执行CanExecute方法.我试图在Command之前设置CommandParameter(如建议的那样) - 但它仍然不起作用.有关如何控制它的任何提示.
Update2:有没有办法检测绑定何时"完成",以便我可以强制重新评估命令?另外 - 我有一个问题,我有多个按钮(ItemsControl中的每个项目一个)绑定到Command对象的同一个实例?
Update3:我已经将错误的副本上传到我的SkyDrive:http://cid-1a08c11c407c0d8e.skydrive.live.com/self.aspx/Code%20samples/CommandParameterBinding.zip
我有一个包含许多对象的WPF/Entity Framework(4.0)项目.我想构建应用程序,以便我可以在视图模型中共享对象选择状态.
例如:我们有汽车,司机,乘客和货物类.我们还有CarList,DriverList等的UserControls以及CarEditor,DriverEditor等的编辑器窗口.此外,我们有所有这些的视图模型(CarListViewModel,DriverListViewModel,CargoEditorViewModel等).这一切都构成了一个可停靠的界面,用户可以在其中打开多个对象列表,编辑器和查看器.
我想要的是如何连接多个视图模型的具体代码示例,以便在CarList中选择汽车将使该汽车在CarEditorView中生效,但也可以在上下文有效的任何其他视图中选择(例如如果有过滤谓词,则为DriverByCarView-或仅为DriverList.
基于这个问题,有许多建议和讨论.似乎占主导地位的两种方法是:
这些方法中的一种比另一种更好吗?
有没有人以书面或小代码项目的形式有这两种方法的具体例子?
我还在学习WPF,所以对于阅读API基础知识的入门点的建议表示赞赏,但查看代码示例是我经常去的地方.
谢谢
如果有人有兴趣,这里有一些其他类似的讨论:
我已经实现类似于在所描述的一个的选择图案此篇使用视图模型来存储IsSelected值,并通过结合所述ListViewItem.IsSelected的视图模型IsSelected:
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="IsSelected" Value="{Binding Mode=TwoWay, Path=IsSelected}"/>
</Style>
</ListView.ItemContainerStyle>
Run Code Online (Sandbox Code Playgroud)
它一般工作,但我遇到了严重的问题.通过VirtualizingStackPanel在列表视图中使用a 作为面板,仅ListViewItem创建了可见的.如果我使用"Ctrl + A"选择所有项目,或者使用第一项上的"Shift + Ctrl + End"快捷键组合,则会选择所有项目,但对于不可见项目,ViewModel不会获取其IsSelected设为true.这是合乎逻辑的,因为如果ListViewItem没有创建,绑定就无法工作.
任何人都遇到了同样的问题,并找到了解决方案(除了不使用a VirtualizingStackPanel)?
我的WPF应用程序中遇到了一个简单的问题,让我在桌面上敲打我的脑袋.我有一个TabControl,其中每个TabItem都是使用类似于此的DataTemplate为ViewModel生成的视图:
<DataTemplate DataType="{x:Type vm:FooViewModel}">
<vw:FooView/>
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)
FooView包含一个ComboBox:
<ComboBox ItemsSource="{Binding Path=BarList}" DisplayMemberPath="Name" SelectedItem="{Binding Path=SelectedBar}"/>
Run Code Online (Sandbox Code Playgroud)
和FooViewModel包含一个简单的属性:public Bar SelectedBar { get; set; }.我的问题是,当我为我的ComboBox设置值时,更改为另一个选项卡,然后更改回来,ComboBox再次为空.如果我在我的属性的setter上设置断点,我看到null当我切换到另一个选项卡时该属性被分配给.
根据我的理解,当切换选项卡时,它将从VisualTree中删除 - 但为什么要将我的ViewModel属性设置为null?这使得我很难保持持久状态,并且检查value != null似乎不是正确的解决方案.任何人都可以在这种情况下摆脱一些吗?
编辑:设置器断点处的调用堆栈仅显示[外部代码] - 没有提示.
有一些帖子讨论ListView.SelectedItems了为非平凡数量的代码添加数据绑定能力.在我的场景中,我不需要设置它ViewModel,只需获取选定的项目以便对它们执行操作并且它由命令触发,因此也不需要推送更新.
是否有一个简单的解决方案(在代码行方面),可能在代码隐藏?只要View并且ViewModel不需要互相引用,我就可以使用代码隐藏.我认为这是一个更通用的问题:" VM从按需查看数据的最佳实践 ",但我似乎找不到任何东西......
当使用MVVM时,我们正在处理视图(而viewmodel仍然存在).
我的问题是如何在ListView视图处理时尽可能接近创建新视图时恢复状态?
ScrollIntoView仅部分工作.我只能滚动到单个项目,它可以在顶部或底部,无法控制项目在视图中的显示位置.
我有多选(和水平滚动条,但这是相当不重要的),有人可能会选择几个项目,也许可以进一步滚动(不改变选择).
理想情况下ScrollViewer,ListView属性与视图模型的绑定可以做到,但我担心直接要求这个问题(不确定这是否适用).此外,在我看来这对于wpf来说是一个非常普遍的事情,但也许我没有正确地制定谷歌查询,因为我找不到相关的ListView+ ScrollViewer+ MVVM组合.
这可能吗?
我有ScrollIntoView和数据模板(MVVM)的问题相当丑陋的变通方法.恢复声音错误的ListView状态ScrollIntoView.应该有另一种方式.今天谷歌引导我到我自己未回答的问题.
我正在寻找恢复ListView状态的解决方案.考虑以下作为mcve:
public class ViewModel
{
public class Item
{
public string Text { get; set; }
public bool IsSelected { get; set; }
public static implicit operator Item(string text) => new Item() { Text = text };
}
public ObservableCollection<Item> Items { get; } …Run Code Online (Sandbox Code Playgroud) 有什么比下面的样本更简单吗?我确实有与DataGrid lstLinks绑定的observable集合(代码中的"list")
for (int i = 0; i < list.Count ; i++)
{
object rowItem = lstLinks.Items[i] ;
DataGridRow visualItem = (DataGridRow)lstLinks.ItemContainerGenerator.ContainerFromItem(rowItem);
if ( visualItem == null ) break;
if (list[i].Changed)
visualItem.IsSelected = false;
else
visualItem.IsSelected = false;
}
Run Code Online (Sandbox Code Playgroud) 我有两个ViewModel,它们为不同的视图提供相同的模型.一个将模型显示为a中的项目ListBox,另一个将其显示为a中的选项卡TabControl.本TabControl是为那些在选定的项目显示选项卡ListBox,从而使标签来来去去,选择的变化.
我可以通过向IsSelectedModel 添加一个属性并将ViewModels绑定到它来轻松地同步这两个控件(有点像这样),但这会使模型与实际上不属于那里的演示细节混乱.
似乎我需要Model和ViewModels之间的东西来保持这个额外的状态.是否有任何好的方法可以做到这一点?
wpf ×8
mvvm ×5
data-binding ×3
listview ×3
xaml ×3
c# ×2
.net ×1
.net-3.5 ×1
binding ×1
command ×1
datagrid ×1
scrollviewer ×1
select ×1
silverlight ×1
stackpanel ×1
wpfdatagrid ×1