WPF - 弹出窗口中包含的图像上的鼠标移动
WPF - MouseMove on image contained in Popup
我用一个图像(HUE 颜色)和一个滑块(亮度级别)制作了一个颜色选择器。
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.8*"/>
<ColumnDefinition Width="0.2*"/>
</Grid.ColumnDefinitions>
<Border x:Name="borderColorChart" Grid.Column="0">
<Grid>
<Image Stretch="Fill" Source="Assets/colorChart.PNG" MouseDown="Image_MouseDown" MouseMove="Image_MouseMove"/>
<Ellipse x:Name="colorMarker" Width="5" Height="5" StrokeThickness="1" Stroke="#FF0B0B0B"/>
</Grid>
</Border>
<Border x:Name="brightnessSliderBorder" Background="{DynamicResource BrightnessGradient}" Grid.Column="1">
<Grid>
<Slider x:Name="brightnessSlider" Orientation="Vertical" IsMoveToPointEnabled="True" Focusable="False" Minimum="0.0" Maximum="1.0" Style="{DynamicResource SliderStyle}" />
</Grid>
</Border>
</Grid>
此颜色选择器包含在当我单击切换按钮时打开的弹出窗口中:
<ToggleButton x:Name="SelectColorChannel1" Grid.Row="0" Background="{Binding SelectedCurrentColor, ElementName=Channel1Color}">
<Popup IsOpen="{Binding IsChecked, ElementName=SelectColorChannel1}" StaysOpen="True">
<CMiX:ColorPicker x:Name="Channel1Color"/>
</Popup>
</ToggleButton>
这是 mousemove 的代码:
private void Image_MouseDown(object sender, MouseButtonEventArgs e)
{
var cb = new CroppedBitmap((BitmapSource)(((Image)e.Source).Source), new Int32Rect((int)Mouse.GetPosition(e.Source as Image).X, (int)Mouse.GetPosition(e.Source as Image).Y, 1, 1));
_pixels = new byte[4];
cb.CopyPixels(_pixels, 4, 0);
UpdateCurrentColor();
UpdateMarkerPosition();
UpdateSlider();
}
private void Image_MouseMove(object sender, MouseEventArgs e)
{
if (Mouse.LeftButton == MouseButtonState.Pressed)
{
if (e.Source.GetType().Equals(typeof(Image)))
{
var cb = new CroppedBitmap((BitmapSource)(((Image)e.Source).Source), new Int32Rect((int)Mouse.GetPosition(e.Source as Image).X, (int)Mouse.GetPosition(e.Source as Image).Y, 1, 1));
_pixels = new byte[4];
cb.CopyPixels(_pixels, 4, 0);
UpdateMarkerPosition();
UpdateCurrentColor();
Mouse.Synchronize();
UpdateSlider();
}
}
}
这里是更新标记位置的函数
private void UpdateMarkerPosition()
{
_markerTransform.X = Mouse.GetPosition(borderColorChart).X - (borderColorChart.ActualWidth / 2);
_markerTransform.Y = Mouse.GetPosition(borderColorChart).Y - (borderColorChart.ActualHeight / 2);
}
问题是,我无法在图像上滑动标记,我只能"click"一次移动它,如果颜色选择器包含在上下文菜单中,则不会发生此问题。但是我需要弹出窗口,所以它在找到图像上正确的颜色和使用滑块时保持打开状态。
有什么提示吗?谢谢
编辑 1 ---
我已经做了一些测试,据我所知,当我使用弹出窗口时,MouseMove 上的 UpdateMarkerPosition() 函数不起作用,但它在我使用上下文菜单的情况下工作......不过,UpdateMarkerPosition() 正在 MouseDown 上工作
编辑 2 ---
好的,现在我清楚地知道这个条件:
if (Mouse.LeftButton == MouseButtonState.Pressed)
如果我使用 wpf Popup
则永远不会是真的
从ToggleButton
内部取出Popup
控制权。并将其单独放置在外面,其 Placement
属性 设置为 Mouse
.
我用一个图像(HUE 颜色)和一个滑块(亮度级别)制作了一个颜色选择器。
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.8*"/>
<ColumnDefinition Width="0.2*"/>
</Grid.ColumnDefinitions>
<Border x:Name="borderColorChart" Grid.Column="0">
<Grid>
<Image Stretch="Fill" Source="Assets/colorChart.PNG" MouseDown="Image_MouseDown" MouseMove="Image_MouseMove"/>
<Ellipse x:Name="colorMarker" Width="5" Height="5" StrokeThickness="1" Stroke="#FF0B0B0B"/>
</Grid>
</Border>
<Border x:Name="brightnessSliderBorder" Background="{DynamicResource BrightnessGradient}" Grid.Column="1">
<Grid>
<Slider x:Name="brightnessSlider" Orientation="Vertical" IsMoveToPointEnabled="True" Focusable="False" Minimum="0.0" Maximum="1.0" Style="{DynamicResource SliderStyle}" />
</Grid>
</Border>
</Grid>
此颜色选择器包含在当我单击切换按钮时打开的弹出窗口中:
<ToggleButton x:Name="SelectColorChannel1" Grid.Row="0" Background="{Binding SelectedCurrentColor, ElementName=Channel1Color}">
<Popup IsOpen="{Binding IsChecked, ElementName=SelectColorChannel1}" StaysOpen="True">
<CMiX:ColorPicker x:Name="Channel1Color"/>
</Popup>
</ToggleButton>
这是 mousemove 的代码:
private void Image_MouseDown(object sender, MouseButtonEventArgs e)
{
var cb = new CroppedBitmap((BitmapSource)(((Image)e.Source).Source), new Int32Rect((int)Mouse.GetPosition(e.Source as Image).X, (int)Mouse.GetPosition(e.Source as Image).Y, 1, 1));
_pixels = new byte[4];
cb.CopyPixels(_pixels, 4, 0);
UpdateCurrentColor();
UpdateMarkerPosition();
UpdateSlider();
}
private void Image_MouseMove(object sender, MouseEventArgs e)
{
if (Mouse.LeftButton == MouseButtonState.Pressed)
{
if (e.Source.GetType().Equals(typeof(Image)))
{
var cb = new CroppedBitmap((BitmapSource)(((Image)e.Source).Source), new Int32Rect((int)Mouse.GetPosition(e.Source as Image).X, (int)Mouse.GetPosition(e.Source as Image).Y, 1, 1));
_pixels = new byte[4];
cb.CopyPixels(_pixels, 4, 0);
UpdateMarkerPosition();
UpdateCurrentColor();
Mouse.Synchronize();
UpdateSlider();
}
}
}
这里是更新标记位置的函数
private void UpdateMarkerPosition()
{
_markerTransform.X = Mouse.GetPosition(borderColorChart).X - (borderColorChart.ActualWidth / 2);
_markerTransform.Y = Mouse.GetPosition(borderColorChart).Y - (borderColorChart.ActualHeight / 2);
}
问题是,我无法在图像上滑动标记,我只能"click"一次移动它,如果颜色选择器包含在上下文菜单中,则不会发生此问题。但是我需要弹出窗口,所以它在找到图像上正确的颜色和使用滑块时保持打开状态。
有什么提示吗?谢谢
编辑 1 --- 我已经做了一些测试,据我所知,当我使用弹出窗口时,MouseMove 上的 UpdateMarkerPosition() 函数不起作用,但它在我使用上下文菜单的情况下工作......不过,UpdateMarkerPosition() 正在 MouseDown 上工作
编辑 2 --- 好的,现在我清楚地知道这个条件:
if (Mouse.LeftButton == MouseButtonState.Pressed)
如果我使用 wpf Popup
则永远不会是真的从ToggleButton
内部取出Popup
控制权。并将其单独放置在外面,其 Placement
属性 设置为 Mouse
.