WPF - 명령의 CanExecute가 false일 경우 메뉴 항목을 숨기는 방법
명령을 실행할 수 없는 경우 기본적으로 메뉴 항목은 비활성화됩니다(CanExecute = false).CanExecute 메서드에 따라 메뉴 항목을 표시/축소하는 가장 쉬운 방법은 무엇입니까?
해결해주셔서 감사합니다.명시적인 XAML을 필요로 하는 사용자에게 이것은 도움이 될 수 있습니다.
<Window.Resources>
<BooleanToVisibilityConverter x:Key="booleanToVisibilityConverter" />
</Window.Resources>
<ContextMenu x:Key="innerResultsContextMenu">
<MenuItem Header="Open"
Command="{x:Static local:Commands.AccountOpened}"
CommandParameter="{Binding Path=PlacementTarget.DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}}"
CommandTarget="{Binding Path=PlacementTarget, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}}"
Visibility="{Binding Path=IsEnabled, RelativeSource={RelativeSource Self}, Mode=OneWay, Converter={StaticResource booleanToVisibilityConverter}}"
/>
</ContextMenu>
이 경우 컨텍스트메뉴는 리소스이므로 가시성을 위한 바인딩은 RelativeSource Self 바인딩 설정을 사용해야 합니다.
한편 CommandParameter의 경우 컨텍스트 메뉴를 열기 위해 클릭한 항목의 DataContext를 전달할 수도 있습니다.명령어 바인딩을 부모창으로 라우팅하려면 그에 따라 명령어타깃도 설정해야 합니다.
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Visibility" Value="Collapsed"/>
</Trigger>
</Style.Triggers>
CanExecute
를 토글하다IsEnabled
속성을 확인하시고 UI에 모든 내용을 저장해 두세요.이 유형을 재사용하려면 별도의 유형을 작성하십시오.
가시성을 IsEnabled에 바인딩하기만 하면 됩니다(CanExecute == false에서 false로 설정).부울을 표시/축소 상태로 변환하려면 IValue Converter가 필요합니다.
public class BooleanToCollapsedVisibilityConverter : IValueConverter
{
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
//reverse conversion (false=>Visible, true=>collapsed) on any given parameter
bool input = (null == parameter) ? (bool)value : !((bool)value);
return (input) ? Visibility.Visible : Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
#endregion
}
Microsoft 는 Boolean ToVisibility Converter 를 제공하고 있습니다.
http://msdn.microsoft.com/en-us/library/system.windows.controls.booleantovisibilityconverter.aspx
이것이 가장 쉬운 방법인지는 모르겠지만 언제든지 속성을 생성하여CanExecute()
그런 다음 visibility를 사용하여 요소의 visibility를 사용하여IValueConverter
부울을 가시성으로 변환합니다.
IsEnabled에 대한 가시성 바인딩은 성공하지만 필요한 XAML은 불쾌할 정도로 길고 복잡합니다.
Visibility="{Binding Path=IsEnabled, RelativeSource={RelativeSource Self}, Mode=OneWay, Converter={StaticResource booleanToVisibilityConverter}}"
첨부된 속성을 사용하여 모든 바인딩 세부사항을 숨기고 의도를 명확하게 전달할 수 있습니다.
첨부된 속성은 다음과 같습니다.
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
namespace MyNamespace
{
public static class Bindings
{
public static bool GetVisibilityToEnabled(DependencyObject obj)
{
return (bool)obj.GetValue(VisibilityToEnabledProperty);
}
public static void SetVisibilityToEnabled(DependencyObject obj, bool value)
{
obj.SetValue(VisibilityToEnabledProperty, value);
}
public static readonly DependencyProperty VisibilityToEnabledProperty =
DependencyProperty.RegisterAttached("VisibilityToEnabled", typeof(bool), typeof(Bindings), new PropertyMetadata(false, OnVisibilityToEnabledChanged));
private static void OnVisibilityToEnabledChanged(object sender, DependencyPropertyChangedEventArgs args)
{
if (sender is FrameworkElement element)
{
if ((bool)args.NewValue)
{
Binding b = new Binding
{
Source = element,
Path = new PropertyPath(nameof(FrameworkElement.IsEnabled)),
Converter = new BooleanToVisibilityConverter()
};
element.SetBinding(UIElement.VisibilityProperty, b);
}
else
{
BindingOperations.ClearBinding(element, UIElement.VisibilityProperty);
}
}
}
}
}
사용 방법은 다음과 같습니다.
<Window x:Class="MyNamespace.SomeClass"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MyNamespace">
<ContextMenu x:Key="bazContextMenu">
<MenuItem Header="Open"
Command="{x:Static local:FooCommand}"
local:Bindings.VisibilityToEnabled="True"/>
</ContextMenu>
</Window>
언급URL : https://stackoverflow.com/questions/3761672/wpf-how-to-hide-menu-item-if-commands-canexecute-is-false
'programing' 카테고리의 다른 글
Asp.NET Web API - 405 - 이 페이지에 액세스하는 데 사용되는 HTTP 동사는 허용되지 않습니다 - 핸들러 매핑 설정 방법 (0) | 2023.04.20 |
---|---|
WPF 데이터 그리드의 날짜 형식 (0) | 2023.04.20 |
VBA에서 폼에서 모듈로의 변수 전달 (0) | 2023.04.20 |
MVVM에서 ViewModelBase를 쓰는 방법 (0) | 2023.04.20 |
각 사용자의 최신 레코드 날짜에 대해 sql을 쿼리하려면 어떻게 해야 합니까? (0) | 2023.04.20 |