Преобразуйте его в строку, затем сравните:
NSString* numberA = [NSString stringWithFormat:@"%.6f", a];
NSString* numberB = [NSString stringWithFormat:@"%.6f", b];
return [numberA isEqualToString: numberB];
Вам нужно будет использовать TranslatePoint
для преобразования верхнего левого угла (0, 0) ContextMenu
в координату в содержащей его сетке. Вы можете сделать это, привязав CommandParameter
к ContextMenu
и используя конвертер:
CommandParameter="{Binding IsOpen, ElementName=_menu, Converter={StaticResource PointConverter}}"
Другой подход - присоединенное поведение, которое автоматически обновляет присоединенное свойство типа только для чтения. Указывайте
всякий раз, когда открывается 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
было открыто в последний раз.
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
было открыто в последний раз.
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
было открыто в последний раз.
<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
было открыто в последний раз.
<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
было открыто в последний раз.
В дополнение к ответу Кента подумайте о «стандартном способе». Например, когда ListBox имеет ContextMenu, вам не нужна позиция меню, потому что выбранный элемент устанавливается до появления меню. Итак, если в вашем элементе управления есть что-то, что "выбирается" правой кнопкой мыши ...
Следуя ответу Кента, я использовал его предложение присоединенного свойства и в итоге получил следующее (используя пример Джоша Смита для присоединенного поведения ):
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
.