我在画布中添加了一个带有C#代码的Line
,以及一个上下文菜单和附加的事件。我想使用上下文菜单选项旋转Line
,而不是上下文菜单中的菜单文本:
newMenuItem1.PreviewMouseDown += new MouseButtonEventHandler((sx, ex) => {
MenuItem menuItem = (MenuItem)sx; string theHeader = menuItem.Header.ToString(); if (theHeader.Contains("90")) { Line ow = ex.Source as Line; rt = new RotateTransform(90, 25, 50); ow.RenderTransform = rt; } });
此代码生成一个null reference exception
。如果我替换:
UIElement ow=ex.来源为UIElement;
实际菜单文本将旋转!
编辑:这是更多的代码,我现在也在尝试originalsource
:
private void button1_Click(object sender, RoutedEventArgs e)
{
Line g = new Line();
g.Stroke = System.Windows.Media.Brushes.LawnGreen;
g.X1 = 0; g.X2 = 100;g.Y1 = 0;g.Y2 = 0;
g.HorizontalAlignment = HorizontalAlignment.Left;
g.VerticalAlignment = VerticalAlignment.Center;
g.StrokeThickness = 6;
ContextMenu k = new ContextMenu();
g.ContextMenu = k;
MenuItem newMenuItem1 = new MenuItem();
MenuItem newMenuItem2 = new MenuItem();
MenuItem newMenuItem3 = new MenuItem();
newMenuItem1.Header = "Rotate 90";
newMenuItem2.Header = "Rotate 180";
newMenuItem3.Header = "Rotate 270";
newMenuItem1.PreviewMouseDown += new MouseButtonEventHandler((sx, ex) => {
MenuItem menuItem = (MenuItem)sx;
string theHeader = menuItem.Header.ToString();
if (theHeader.Contains("90")) {
Line ow = (Line)ex.OriginalSource;
rt = new RotateTransform(90, 25, 50);
ow.RenderTransform = rt;
}
});
g.ContextMenu.Items.Add(newMenuItem1);
g.ContextMenu.Items.Add(newMenuItem2);
g.ContextMenu.Items.Add(newMenuItem3);
Canvas.SetTop(g, 18);
Canvas.SetLeft(g, 18);
MyCanvas.Children.Add(g);
///////
我也试过:
private static T FindAncestor<T>(DependencyObject current)
where T : DependencyObject
{
do
{
if (current is T)
{
return (T)current;
}
current = VisualTreeHelper.GetParent(current);
}
while (current != null);
return null;
}
但它不起作用。我的下一个计划是从画布上获取坐标,并尝试确定那里有什么控件。不过,如果对象被转换,这将变得棘手,因为我相信UI会在原始位置看到它。我也尝试过其他控件,比如TextBox
,但也遇到了类似的问题。
一个真正快速而肮脏的方法是将行添加到菜单项的标记属性中,并在PreviewMouseDown处理程序中检索它
创建上下文菜单时:
newMenuItem1.Tag = g;
内部处理程序:
Line ow = ((FrameworkElement)ex.Source).Tag as Line;
要做到这一点,不那么快速和肮脏的方法是在您的行中使用ContextMenuOpening事件,因为发送该事件的发送方应等于控件本身。然后,您可以将对该行的引用存储在某个位置,并在菜单项单击事件中再次检索该行。当你有多行(我想这就是你想要的)和只有一个上下文菜单(而不是像现在这样生成同一菜单的一堆副本)时,效果会更好。