-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/>
之后一切正常。
我注意到一个奇怪的错误。当我将命令绑定到 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/>
之后一切正常。