Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
WPF C#UserControl DependencyProperty命令绑定为null_C#_Wpf_Xaml_Viewmodel_Commandbinding - Fatal编程技术网

WPF C#UserControl DependencyProperty命令绑定为null

WPF C#UserControl DependencyProperty命令绑定为null,c#,wpf,xaml,viewmodel,commandbinding,C#,Wpf,Xaml,Viewmodel,Commandbinding,我创建了一个UserControl作为文件浏览工具,我想实现命令作为dependencProperties进行加载和保存,这样我就可以从视图模型绑定命令,以便处理它们 现在的问题是,如果我使用预定义的命令如打开或保存并在我的窗口中处理它们,它会起作用,但是如果我从我的视图模型使用绑定,这些命令是空的 下面的代码是一个示例程序,其中我删除了对我的问题不重要的所有内容,因为这可能是太多的代码 用户控制 XAML 代码隐藏 视图模型 使用System.ComponentModel; 使用Sys

我创建了一个
UserControl
作为文件浏览工具,我想实现
命令
作为
dependencProperties
进行加载和保存,这样我就可以从
视图模型
绑定
命令
,以便处理它们

现在的问题是,如果我使用预定义的
命令
打开
保存
并在我的
窗口
中处理它们,它会起作用,但是如果我从我的
视图模型
使用
绑定
,这些
命令
空的

下面的代码是一个示例程序,其中我删除了对我的问题不重要的所有内容,因为这可能是太多的代码


用户控制 XAML

代码隐藏 视图模型
使用System.ComponentModel;
使用System.Runtime.CompilerServices;
使用System.Windows.Input;
使用Prism.命令;
命名空间WpfApplication1.Models
{
公共类UserControlViewModel
:inotifyproperty已更改
{
公共事件属性更改事件处理程序属性更改;
公共DelegateCommand ExecuteCommand{get;}
私有void ExecuteCommand_Executed(ICommand cmd)=>cmd?.Execute(“C:\\Test.txt”);
私有无效通知([CallerMemberName]字符串名称=null)
{
if(name!=null)
PropertyChanged?.Invoke(这是新的PropertyChangedEventArgs(名称));
}
公共用户控制视图模型()
{
ExecuteCommand=新的DelegateCommand(ExecuteCommand_已执行);
}
}
}

窗口 XAML 视图模型
使用System.ComponentModel;
使用System.Runtime.CompilerServices;
使用System.Windows;
使用Prism.命令;
命名空间WpfApplication1.Models
{
公共类MainWindowViewModel:INotifyPropertyChanged
{
公共事件属性更改事件处理程序属性更改;
公共DelegateCommand OpenCommand{get;}
已执行私有void OpenCommand_(字符串文件)
{
Show($“Model:{file}”);
}
私有无效通知([CallerMemberName]字符串名称=null)
{
PropertyChanged?.Invoke(这是新的PropertyChangedEventArgs(名称));
}
公共主窗口视图模型()
{
OpenCommand=新的DelegateCommand(执行OpenCommand_);
}
}
}

该窗口包含一个预定义的
Open命令
,该命令以这种方式工作,但
绑定
不起作用


为了运行这个应用程序,您需要Prism.Wpf NuGet包。

看起来您在这里找到了一些奇怪的东西。但套用我一位朋友的话说,“好消息是,这次癌症更容易治疗”

首先,我使用PresentationTraceSources.TraceLevel对您的绑定进行了活检:

<local:TestControl 
    LoadCommand="{Binding 
                    Source={StaticResource ViewModel}, 
                    Path=OpenCommand, 
                    PresentationTraceSources.TraceLevel=High}" 
    />
TestControl
有自己的资源和键
ViewModel
,所以这就是查找的结果。该资源是一个
UserControlViewModel
,它没有
OpenCommand
属性,在这种情况下,它在
MainWindow
中以相同的名称隐藏完全不同的资源

我不知道这个viewmodel资源方案是从哪里来的,但可以看出这是一个严重的错误。
main窗口中的任何人都不必担心在
TestControl
中内部使用了哪些资源键

幸运的是,没有必要制造这个问题。您可以删除一段代码,最终得到更简单、更健壮、更可维护的东西

因此,要解决问题:

首先,不要将所有ViewModel都创建为资源,因为没有理由这样做,这会导致问题。将此
ExecuteCommand
绑定与您拥有的绑定进行比较。你从这些东西中得到了什么?没有什么。如果您费心设置
DataContext
,请将其用作DataContext


最后,用户控件创建自己的视图模型通常是不好的做法,其原因现在已经非常明显了。我发现,当它们继承其父级的
DataContext
时,混淆就少多了。但是我已经把你的设计抛到窗外一天了,所以我们就不谈了

感谢您的快速回答,但我更改了
命令
,但没有任何帮助。同样,如果没有通过
ViewModel
来“路由”命令,我无法添加一些自动行为,比如“真的覆盖了这个文件?”之类的东西。真正让我抓狂的是,如果我只是将我的
UserControl
扔到
窗口上,使用预定义的
Open
命令,而不使用任何
ViewModel
一切正常。。。但如果我想把一切都做好,添加一个
ViewModel
并尝试将LoadCommand绑定到my
ViewModel
的命令中我可以在
UserControl
后面的cody中看到
dependencProperty
是空的。是的,我在my
UserControl
上定义了
dependencProperty
,在my
上定义了
DelegateCommand
ViewModel
。我的
UserControl
上的一个功能就是能够稍后在
XAML
级别的
窗口中添加
绑定
,并将
命令绑定
传递到
视图模型
中,我在其中声明了绑定,以便添加一些监视和默认行为,如“文件确实存在”仔细想想,我想我可能猜错了你保守秘密的一些密码。您是否正在设置
DataContext=this在你的用户控件中?您需要共享用户控件的完整代码,并显示viewmodel的来源。实际上是否有一个名为
ViewModel
StaticResource
?如果是这样,在哪里?@dukemadcat我无法从你现在的状态重建你的代码
<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApplication1"
        xmlns:models="clr-namespace:WpfApplication1.Models"
        mc:Ignorable="d"
        Title="MainWindow" Height="200" Width="200">
    <Window.Resources>
        <models:MainWindowViewModel x:Key="ViewModel"/>
    </Window.Resources>
    <Window.DataContext>
        <Binding Source="{StaticResource ViewModel}"/>
    </Window.DataContext>
    <Window.CommandBindings>
        <CommandBinding Command="Open" Executed="CommandBinding_Executed"/>
    </Window.CommandBindings>
    <StackPanel VerticalAlignment="Center">
        <local:TestControl LoadCommand="{Binding Path=OpenCommand, Source={StaticResource ViewModel}}"/>
        <local:TestControl LoadCommand="Open"/>
    </StackPanel>
</Window>
<local:TestControl 
    LoadCommand="{Binding 
                    Source={StaticResource ViewModel}, 
                    Path=OpenCommand, 
                    PresentationTraceSources.TraceLevel=High}" 
    />
System.Windows.Data Warning: 56 : Created BindingExpression (hash=34810426) for Binding (hash=11882558)
System.Windows.Data Warning: 58 :   Path: 'OpenCommand'
System.Windows.Data Warning: 60 : BindingExpression (hash=34810426): Default mode resolved to OneWay
System.Windows.Data Warning: 61 : BindingExpression (hash=34810426): Default update trigger resolved to PropertyChanged
System.Windows.Data Warning: 62 : BindingExpression (hash=34810426): Attach to WpfApplication1.TestControl.LoadCommand (hash=5114324)
System.Windows.Data Warning: 67 : BindingExpression (hash=34810426): Resolving source 
System.Windows.Data Warning: 70 : BindingExpression (hash=34810426): Found data context element: <null> (OK)
System.Windows.Data Warning: 78 : BindingExpression (hash=34810426): Activate with root item UserControlViewModel (hash=33108977)
System.Windows.Data Warning: 108 : BindingExpression (hash=34810426):   At level 0 - for UserControlViewModel.OpenCommand found accessor <null>
System.Windows.Data Error: 40 : BindingExpression path error: 'OpenCommand' property not found on 'object' ''UserControlViewModel' (HashCode=33108977)'. BindingExpression:Path=OpenCommand; DataItem='UserControlViewModel' (HashCode=33108977); target element is 'TestControl' (Name=''); target property is 'LoadCommand' (type 'ICommand')
System.Windows.Data Warning: 80 : BindingExpression (hash=34810426): TransferValue - got raw value {DependencyProperty.UnsetValue}
System.Windows.Data Warning: 88 : BindingExpression (hash=34810426): TransferValue - using fallback/default value <null>
System.Windows.Data Warning: 89 : BindingExpression (hash=34810426): TransferValue - using final value <null>
public TestControl()
{
    InitializeComponent();

    var x = FindResource("ViewModel");

    //  Set breakpoint here and inspect x
    ;
}
<UserControl.DataContext>
    <models:UserControlViewModel />
</UserControl.DataContext>
<Grid>
    <Button Content="_Load" IsDefault="True"
        Command="{Binding ExecuteCommand}"
        CommandParameter="{Binding Path=LoadCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:TestControl}}}"/>
</Grid>
<Window.DataContext>
    <models:MainWindowViewModel />
</Window.DataContext>

<StackPanel VerticalAlignment="Center">
    <!-- 
    local:TestControl.DataContext is its own viewmodel, so we use RelativeSource
    to get to the Window, and then we look at Window.DataContext for the main window
    viewmodel. 
    -->
    <local:TestControl 
        LoadCommand="{Binding DataContext.OpenCommand, RelativeSource={RelativeSource AncestorType=Window}}" 
        />
</StackPanel>