سؤال

ومشكلة مثيرة للاهتمام تتعلق بإطلاق الأوامر من عناصر القائمة السياق ...

وأريد أن إطلاق الأمر لإدراج صف في بلدي السيطرة، InsertRowCmd. يحتاج هذا الأمر لتعرف من أين إدراج الصف.

وأتمكن من استخدام Mouse.GetPosition ()، ولكن هذا سيحصل لي موقف الماوس حاليا، والتي ستكون على عنصر القائمة. أريد الحصول على أصل قائمة السياق بدلا من ذلك.

هل هناك أي واحد أي اقتراحات بشأن كيفية تمرير أصل قائمة السياق كمعلمة إلى الأمر؟

ونموذج التعليمات البرمجية:

<UserControl x:Name="MyControl">
<!--...-->
        <ContextMenu x:Name="menu">
            <MenuItem Header="Insert Row" Command="{x:Static customCommands:MyCommands.InsertRowCmd}" CommandParameter="?"/>
        </ContextMenu>
</UserControl>

وأفكاري الحالية هي كما يلي:

و-استخدام انقر معالج بدلا بحيث يمكنني العثور على الأصل في التعليمات البرمجية. المشكلة هي أنني بعد ذلك للتعامل مع تمكين / تعطيل.

ومقبض الحدث انقر فوق وحفظ أصل قائمة السياق. تمرير هذه المعلومات المحفوظة في الأمر. ولقد تحققت هذه النقرة أحداث الحريق قبل تنفيذ الأمر.

وأي أفكار؟

تعديل:

وأنا باستخدام جوش سميث <لأ href = "http://www.codeproject.com/KB/WPF/VMCommanding.aspx؟fid=1521948&df=90&mpp=25&noise=3&sort=Position&view=Quick&select=2696866" يختلط = "noreferrer"> CommandSinkBinding لمسار قيادة التعامل مع في صفي ViewModel. ذلك الرمز الذي يعالج تنفيذ الأمر يعرف شيئا عن الرأي.

هل كانت مفيدة؟

المحلول

وستحتاج إلى استخدام TranslatePoint لترجمة العلوية اليسرى (0، 0) من ContextMenu إلى تنسيق في الشبكة التي تحتوي على. هل يمكن أن تفعل ذلك عن طريق ربط CommandParameter إلى ContextMenu واستخدام محول:

CommandParameter="{Binding IsOpen, ElementName=_menu, Converter={StaticResource PointConverter}}"

وثمة نهج آخر سيكون سلوك المرفقة يقوم بتحديث خاصية للقراءة فقط المرفقة نوع Point تلقائيا كلما فتحت ContextMenu. أن استخدام ننظر بشيء من هذا القبيل:

<ContextMenu x:Name="_menu" local:TrackBehavior.TrackOpenLocation="True">
    <MenuItem Command="..." CommandParameter="{Binding Path=(local:TrackBehavior.OpenLocation), ElementName=_menu}"/>
</ContextMenu>

وهكذا الملكية TrackOpenLocation المرفقة يفعل عمل المترتبة على ContextMenu وتحديث خاصية المرفق الثاني (OpenLocation) كلما فتح ContextMenu. ثم MenuItem يمكن ربط فقط لOpenLocation للحصول على الموقع الذي كان ContextMenu آخر فتح.

نصائح أخرى

وبعد يوم من الإجابة كينت، وكنت له تعلق اقتراح الممتلكات وانتهى هذا (باستخدام جوش سميث <لأ href = "http://joshsmithonwpf.wordpress.com/2008/08/30/introduction-to-attached -behaviors / "يختلط =" noreferrer "> مثال لسلوكيات المرفقة ):

public static class TrackBehavior
{
 public static readonly DependencyProperty TrackOpenLocationProperty = DependencyProperty.RegisterAttached("TrackOpenLocation", typeof(bool), typeof(TrackBehavior), new UIPropertyMetadata(false, OnTrackOpenLocationChanged));

 public static bool GetTrackOpenLocation(ContextMenu item)
 {
  return (bool)item.GetValue(TrackOpenLocationProperty);
 }

 public static void SetTrackOpenLocation(ContextMenu item, bool value)
 {
  item.SetValue(TrackOpenLocationProperty, value);
 }

 public static readonly DependencyProperty OpenLocationProperty = DependencyProperty.RegisterAttached("OpenLocation", typeof(Point), typeof(TrackBehavior), new UIPropertyMetadata(new Point()));

 public static Point GetOpenLocation(ContextMenu item)
 {
  return (Point)item.GetValue(OpenLocationProperty);
 }

 public static void SetOpenLocation(ContextMenu item, Point value)
 {
  item.SetValue(OpenLocationProperty, value);
 }

 static void OnTrackOpenLocationChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
 {
  var menu = dependencyObject as ContextMenu;
  if (menu == null)
  {
   return;
  }

  if (!(e.NewValue is bool))
  {
   return;
  }

  if ((bool)e.NewValue)
  {
   menu.Opened += menu_Opened;

  }
  else
  {
   menu.Opened -= menu_Opened;
  }
 }

 static void menu_Opened(object sender, RoutedEventArgs e)
 {
  if (!ReferenceEquals(sender, e.OriginalSource))
  {
   return;
  }

  var menu = e.OriginalSource as ContextMenu;
  if (menu != null)
  {
   SetOpenLocation(menu, Mouse.GetPosition(menu.PlacementTarget));
  }
 }
}

ومن ثم استخدامها في XAML، كل ما تحتاجه هو:

<ContextMenu x:Name="menu" Common:TrackBehavior.TrackOpenLocation="True">
 <MenuItem Command="{Binding SomeCommand}" CommandParameter="{Binding Path=(Common:TrackBehavior.OpenLocation), ElementName=menu}" Header="Menu Text"/>
</ContextMenu>

ولكن، أنا في حاجة أيضا إلى إضافة:

NameScope.SetNameScope(menu, NameScope.GetNameScope(this));

وإلى منشئ وجهة نظري، وإلا فإن ملزمة لCommandParameter لا يمكن البحث ElementName=menu.

وبالإضافة إلى الإجابة كينت، والتفكير في "طريقة قياسية". F.e. عندما مربع القائمة لديه ContextMenu، لا تحتاج موقف القائمة، وبسبب تعيين العنصر المحدد من قبل القائمة برزت. لذا، إذا التحكم الخاصة بك لن يكون شيء أن يحصل على "اختيار" على فوق الحق ...

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top