【问题标题】:EventToCommand is never triggered - MVVM永远不会触发 EventToCommand - MVVM
【发布时间】:2014-11-25 14:14:46
【问题描述】:

我有以下 XAML 代码,用户在每次按下回车按钮时都会提交内容。 EventToCommand 调用 ViewModel 中的 AddFieldCommand 方法。

<TextBox x:Name="txtFields" Text="{Binding FieldsTextProperty, UpdateSourceTrigger=PropertyChanged}" Height="23" TextWrapping="NoWrap" Background="#FFCBEECD" AcceptsReturn="False" >
                <i:Interaction.Triggers>
                    <iex:KeyTrigger Key="Enter">              
                        <cmd:EventToCommand Command="{Binding DataContext.AddFieldCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" PassEventArgsToCommand="True"/>
                    </iex:KeyTrigger>
                </i:Interaction.Triggers>
</TextBox>

属性FieldsTextProperty 在我的 MainViewModel.cs 中定义:

public string FieldsTextProperty { get; set; }

AddFieldCommand 的 ICommand 如下所示:

public ICommand AddFieldCommand { get; private set; } 

并像这样初始化:

AddFieldCommand = new RelayCommand<KeyEventArgs>(AddField);

AddField 方法如下所示:

 public void AddField(KeyEventArgs e)
 {
        FrameworkElement classDataVisualElement = (FrameworkElement)e.KeyboardDevice.Target;
        ClassData classDataModel = (ClassData)classDataVisualElement.DataContext;

        classDataModel.Fields.Add(FieldsTextProperty);

        FieldsTextProperty = "";

        RaisePropertyChanged("Fields");
  }

代码获取当前对象并将TextBox中的内容添加到对象中。

这不起作用,我不明白为什么? 当我按 Enter 并且 FieldsTextPropertyAddField 永远不会被调用时,什么也没有发生

编辑: 我的输出窗口中出现以下错误: 'FieldsTextProperty' property not found on 'object' ''ClassData' (HashCode=46358046)'. BindingExpression:Path=FieldsTextProperty; DataItem='ClassData' (HashCode=46358046); target element is 'TextBox' (Name='txtFields'); target property is 'Text' (type 'String')

编辑 2: 经过几次测试 - 似乎问题出在FieldsTextProperty。我的老朋友 Console.Writeline("AddField Method") 永远不会让人失望 ;)

编辑 3: 完整(几乎)XAML 代码:

<UserControl ..... >

<Grid>
    <TextBlock Text="Class Name" Background="#FF96BB96" Foreground="Black" IsHitTestVisible="True">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="MouseDown">
                <cmd:EventToCommand Command="{Binding DataContext.MouseDownClassDataCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" PassEventArgsToCommand="True"/>
            </i:EventTrigger>
            <i:EventTrigger EventName="MouseMove">
                <cmd:EventToCommand Command="{Binding DataContext.MouseMoveClassDataCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" PassEventArgsToCommand="True"/>
            </i:EventTrigger>
            <i:EventTrigger EventName="MouseUp">
                <cmd:EventToCommand Command="{Binding DataContext.MouseUpClassDataCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" PassEventArgsToCommand="True"/>
            </i:EventTrigger>
        </i:Interaction.Triggers>
    </TextBlock>

    <StackPanel Opacity="{Binding DataContext.ModeOpacity, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}">
        <Border BorderBrush="#FF53855E" BorderThickness="1" Height="25"/>

        <!-- FIELDS ELEMENTS-->
        <Grid>
            <TextBox x:Name="txtFields" Text="{Binding FieldsTextProperty, UpdateSourceTrigger=PropertyChanged}" Height="23" TextWrapping="NoWrap" Background="#FFCBEECD" AcceptsReturn="False" >
                <i:Interaction.Triggers>
                    <iex:KeyTrigger Key="Enter">              
                        <cmd:EventToCommand Command="{Binding DataContext.AddFieldCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" PassEventArgsToCommand="True"/>
                    </iex:KeyTrigger>
                </i:Interaction.Triggers>
            </TextBox>


            <TextBlock IsHitTestVisible="False" Text="Insert Fields.." VerticalAlignment="Center" HorizontalAlignment="Left" Margin="5,0,0,0" Foreground="DarkGray">
                <TextBlock.Style>
                    <Style TargetType="{x:Type TextBlock}">
                        <Setter Property="Visibility" Value="Collapsed"/>
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding Text, ElementName=txtFields}" Value="">
                                <Setter Property="Visibility" Value="Visible"/>
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </TextBlock.Style>
            </TextBlock>
        </Grid>

        <DataGrid x:Name="PropertiesControl1" Height="auto" ItemsSource="{Binding ClassDatas}" HeadersVisibility="None" AutoGenerateColumns="False" CanUserAddRows="False" CanUserDeleteRows="True">
            <DataGrid.Columns>
                <DataGridTextColumn Binding="{Binding Fields}" Header="" Width="*" IsReadOnly="True"/>
            </DataGrid.Columns>
        </DataGrid>

        <!-- More of the same code...-->

    </StackPanel>

</Grid>

</UserControl>

【问题讨论】:

  • 任何绑定错误?查看您的输出窗口 AddFieldCommand ,我猜绑定发生时它为空。

标签: c# wpf mvvm mvvm-light


【解决方案1】:

我有预感.. 绑定发生时命令可能为空。
试试:

   private ICommand _addFieldCommand; 
   public ICommand AddFieldCommand 
   {
       get
       {
            if(_addFieldCommand == null)
                _addFieldCommand = new RelayCommand<KeyEventArgs>(AddField);
            return _addFieldCommand;  
       }
   } 

XAML:

     <UserControl DataContext"={Binding Path=DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}">

【讨论】:

  • 它不会改变任何东西。但我有以下错误:'FieldsTextProperty' 属性未在'object'''ClassData'(HashCode=46358046)'上找到。 BindingExpression:Path=FieldsTextProperty; DataItem='ClassData' (HashCode=46358046);目标元素是'TextBox'(名称='txtFields');目标属性是“文本”(类型“字符串”)
  • 那么你的 DataContext 是一个 ClassData 实例而不是 MainViewModel。请显示您的 TextBox 所在位置的简短 xaml。
  • 我添加了一个短 XAML。
  • 你的 UserControl 的 DataContext 是 ClassData 的一个实例,而不是 MainViewModel
  • 如何更改 DataContext,使其成为 MainViewModel 的实例?
【解决方案2】:

尝试添加:

AddFieldCommand.CanExecute = true;

初始化命令后

【讨论】:

  • 无论我把你的代码放在哪里,我都会收到来自 VS 的错误。应该放在Constructor中,方法中还是?
  • 它应该放在你初始化RelayCommand的行之后的构造函数中更多关于CanExecute的信息找到here
  • @user1: CanExecute 是Func&lt;bool&gt;,改成true 没有意义。
猜你喜欢
  • 2014-05-15
  • 2021-05-22
  • 2015-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-19
  • 2016-06-12
相关资源
最近更新 更多