【问题标题】:problem with wpf command not executing when button clicked单击按钮时 wpf 命令未执行的问题
【发布时间】:2011-09-28 20:53:51
【问题描述】:

我在 WPF 应用程序中有以下 XAML。我想将按钮绑定到视图模型中的ICommand。出于某种原因,我无法从我的视图中看到该命令。 这是在用户控件中。

<Grid>
<Grid.DataContext>
        <Binding 
            x:Name="SettingsData"
            Path="Data" />
    </Grid.DataContext>
.
.
.
<DockPanel Grid.Column="1">
            <Button x:Name="SaveButton" 
                    DockPanel.Dock="Top"  
                    Height="25"  
                    HorizontalAlignment="Left" 
                    Margin="70 0 0 0"
                    Command="{Binding Path=SaveData}"

                    >Save Changes</Button>
        </DockPanel>
</Grid>

这是我的 ICommand 对象 -

public ICommand SaveData
{
    get
    {
        if (_saveData == null)
        {
            _saveData = new RelayCommand(
                param => this.saveData(),
                param => true
                );
        }
        return _saveData ;
    }
}

有人知道为什么我不能绑定到这个命令吗?

感谢您的任何想法......

【问题讨论】:

  • RelayCommand 的实现是什么,它不属于标准的 WPF 库?我猜 CanExecute 返回 false。
  • 我正在使用 Josh Smith 的 MVVM 教程 - msdn.microsoft.com/en-us/magazine/dd419663.aspx 中的 relaycommand 实现。第二个参数是 CanExecute,所以我总是发送 true....
  • 调试时是否可以在 VS 输出窗口中看到任何绑定错误?
  • 我在输出窗口中看到了这个 - BindingExpression 路径错误:在 'object' ''List`1' 上找不到 'SaveData' 属性
  • 您是否使用PresentationTraceSources.TraceLevel=High 调试了绑定以查看是否一切正常?

标签: c# wpf xaml binding


【解决方案1】:

看起来您正在将 GridDataContext 设置为 ViewModel(或对象)的 Data 属性。如果 Data 属性公开的对象不提供 SaveData 命令,那么您将遇到您所描述的问题。请记住 DataContext 是从父级继承的。

如果您要求DataContext 以这种方式设置,并且仍然需要按钮来引用父DataContext,则一种选择是使用RelativeSource 指向以ViewModel 作为@ 的元素987654328@.

在 WPF 中,您还可以选择将这些命令设为静态并使用 {x:Static} 标记扩展来访问它。

希望对您有所帮助。

编辑:如果您的 &lt;Grid&gt; 包含在 &lt;UserControl&gt; 中,这是一个示例。

<Button Command="{Binding Path=DataContext.SaveData, 
                          RelativeSource={RelativeSource Mode=FindAncestor, 
                                          AncestorType={x:Type UserControl}}}" ... />

另外,我不知道你的完整 XAML 是什么样子,但我怀疑这可以通过删除 Grid 上的 DataContextItemsControl 上的绑定数据(或任何你的用于显示对象列表)。

【讨论】:

  • savedata 命令确实驻留在与网格绑定的同一视图模型中。它不应该能看到吗?
  • 不,Button的DataContext是ViewModel.Data,不是ViewModel。因此,您正在尝试绑定到 ViewModel.Data.SaveData。 (从您的错误来看,数据似乎是某个对象的列表)。
  • 那么我是否必须将按钮的datacontext设置为viewmodel?
  • 是的。但是有一些方法可以在不显式设置 Xaml 或代码的情况下获取它,包括使用 RelativeSource 或 ElementName 指向已经将 DataContext 设置为 ViewModel(很可能是 Grid 的父级)的 UIElement。
  • 网格的父级是实际的用户控件。如果我将 elementname 设置为此,我仍然会收到错误。
【解决方案2】:

查看以下错误,您的 DockPanel 上的 DataContext 似乎绑定到某种列表:

我在输出窗口中看到了这个 - BindingExpression 路径错误: 在“对象”“List`1”上找不到“SaveData”属性

如果DataContext不在顶层,请覆盖Binding中的Source属性

【讨论】:

  • 我应该将源设置为视图模型的名称吗?
  • 我通常在后面的代码中设置 DataContext。你是如何设置你的 View 的 DataContext 的?
  • 我在视图的xaml中设置了如上所示的网格级别
猜你喜欢
  • 2013-01-23
  • 1970-01-01
  • 2016-03-02
  • 1970-01-01
  • 2012-05-29
  • 1970-01-01
  • 2012-01-15
  • 2014-02-16
  • 2021-07-04
相关资源
最近更新 更多