-wpf canvas 事件仅在第一次触发

-wpf canvas events firing only for first time

我注意到一个奇怪的错误。当我将命令绑定到 canvas MouseLeftButtonDown 事件时,它不会触发。我尝试调试并注意到它会触发,但仅在初始化期间触发。我想关键在于绑定。这是代码:

<ItemsControl Grid.Row="1" ItemsSource="{Binding Polygons}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <Canvas>
                   <i:Interaction.Behaviors>
                        <behaviours:MouseBehaviour MouseX="{Binding MouseX, Mode=OneWayToSource}" MouseY="{Binding MouseY, Mode=OneWayToSource}" />
                    </i:Interaction.Behaviors>

                    <i:Interaction.Triggers>
                        <i:EventTrigger EventName="MouseLeftButtonDown">
                            <command:EventToCommand Command="{Binding SelectPointCommand}"/>
                        </i:EventTrigger>
                    </i:Interaction.Triggers>
                </Canvas>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
               /* some data template
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>

以及命令实现:

 public ICommand SelectPointCommand
    {
        get
        {
            if (!CanEdit)
                return new RelayCommand(e => { });

            ClickCounter++;

            if (ClickCounter == 3)
            {
                ClickCounter = 0;
                CanEdit = false;
            }

            return new RelayCommand(
                () =>
                {
                    Polygons.Add(new Polygon(ClickedPoints));
                    ClickedPoints.Clear();
                });
        }
    }

我猜这里的问题出在 MouseBehaviour 中,但删除这段代码也没有帮助。

ps :我尝试设置 canvas 背景 属性 但没有成功。 以及为此

设置命令
 SelectPointCommand = new RelayCommand(
        () =>
        {
            System.Windows.MessageBox.Show("Test");
        }, 
        () => true);

编辑 我试过这样调用方法:

 <Canvas Background="Transparent" MouseLeftButtonDown="UIElement_OnMouseLeftButtonDown">

</Canvas>

后面的代码:

private void UIElement_OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
       ((MainViewModel)DataContext).SelectPointCommand.Execute(e);
    }

方法UIElement_OnMouseLeftButtonDown无论如何都不会被调用; 将 Canvas 更改为 StackPanel 具有相同的结果。

很难检查出什么问题,因为您没有 post 所有代码。 CanEdit 属性 是不是在其他一些地方改了? ClickCounter 有什么用?

我认为问题出在 SelectPointCommand 的 getter 上。它只在创建绑定时执行一次。我还将使用 ICommand 的 CanExecute 方法并将 getter 的返回值存储在私有字段中。例如:

    private ICommand _selectPointCommand;
    ICommand SelectPointCommand
    {
        get
        {
            Console.WriteLine("This is executed once");
            return _selectPointCommand;
        }

        set
        {
            if (_selectPointCommand != value)
            {
                _selectPointCommand = value;
                OnPropertyChanged("SelectPointCommand");
            }
        }
    }

在 ViewModel 的构造函数中:

        SelectPointCommand = new RelayCommand(
                (x) =>
                {
                    Console.WriteLine("This is executed every click");
                    ClickCounter++;

                    if (ClickCounter == 3)
                    {
                        ClickCounter = 0;
                        CanEdit = false;
                    }
                    Polygons.Add(new Polygon(ClickedPoints));
                    ClickedPoints.Clear();
                },
                (x) => { return CanEdit; });

好的伙计们,我修复了这个错误。问题出在这里:

 <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto"/>
 </Grid.RowDefinitions>

将行的高度设置为 "Auto" 意味着将其设置为零。所以 canvas 根本不存在!我是这样离开的:

 <RowDefinition/>

之后一切正常。