Command.CanExecute返回false时折叠超链接

时间:2012-12-04 15:01:44

标签: wpf xaml

简单的问题是:当绑定命令.CanExecute返回false时,如何隐藏超链接?

xaml:

<TextBlock>
    <Hyperlink Command="{Binding IncludesCanExecuteCommand}">Link text</Hyperlink>
</TextBlock>

代码:

...
private ICommand _includesCanExecuteCommand;
....
    _includesCanExecuteCommand = new RelayCommand(ExecuteTheCommand, CanExecuteTheCommand);
....

public ICommand IncludesCanExecuteCommand
{
    get
    {
        return _includesCanExecuteCommand;
    }
}

....

public bool CanExecuteTheCommand()
{
    return BooleanResult();
}

public void ExecuteTheCommand()
{
    DoSomeWork();
}

如何设置Textblock / Hyperlink(或运行,如果需要),以便在CanExecute()函数返回false时链接崩溃?我试过了:

<Hyperlink.Style>
    <Style TargetType="{x:Type Hyperlink}" BasedOn="{StaticResource DefaultHyperlinkStyle}">
        <Setter Property="TextBlock.Visibility" Value="Visible" />
        <Style.Triggers>
            <Trigger Property="IsEnabled" Value="False">
                <Setter Property="TextBlock.Visibility" Value="Collapsed" />
            </Trigger>
        </Style.Triggers>
     </Style>
 </Hyperlink.Style>                        

我也尝试将样式放在文本块上(无法获取超链接)和超链接中的Run(无可见性属性)。

感谢所有的想法!

4 个答案:

答案 0 :(得分:0)

所以这里似乎有两个问题..

我可能很想在打电话后设置一个属性     IncludesCanExecuteCommand.RaiseCanExecuteChanged() 这将导致命令重新评估其CanExecuteCommand ..

将超链接放在面板中,然后将可见性与1.)中的属性绑定,并使用转换器返回有效的Visiblility枚举,例如Collapsed,Visible等。

为了清楚起见 - 类似

<StackPanel Visibility="{Binding IsHyperlinkVisible, Mode=TwoWay,     Converter=boolToVisibilityConverter}">
  <TextBlock>
    <Hyperlink Command="{Binding WhateverTheHyperlinkDoesCommand}">Link text</Hyperlink>
</TextBlock>
</StackPanel>

并且viewmodel看起来像这样(如果viewmodelbase实现了某个版本的NotifyPropertyChanged ...

 public class ViewModel : NotificationViewModelBase 
 {
        public ViewModel()
        {
            this.WhateverTheHyperlinkDoesCommand =
                new DelegateCommand<object>(
                    this.ExecuteWhateverTheHyperlinkDoesCommand, this.CanWhateverTheHyperlinkDoesCommand);
        }

        private void ExecuteWhateverTheHyperlinkDoesCommand(object arg)
        {
            this.SomeOtherProperty = true;            }

        private bool someOtherProperty;

        public bool SomeOtherProperty
        {
            get
            {
                return this.someOtherProperty;
            }

            set
            {
                if (this.ChangeAndRaisePropertyChanged(
                    () => this.SomeOtherProperty, value, ref this.someOtherProperty))
                {
                    this.WhateverTheHyperlinkDoesCommand.RaiseCanExecuteChanged();
                }
            }
        }

            private bool isHyperlinkProperty;

        public bool IsHyperlinkProperty
        {
            get
            {
                return this.isHyperlinkProperty;
            }

            set
            {
                this.ChangeAndRaisePropertyChanged(() => this.IsHyperlinkProperty, value, ref this.isHyperlinkProperty);
            }
        }

        private bool CanWhateverTheHyperlinkDoesCommand(object obj)
        {
            // So based on a certain condition - lets say some other property

            if (this.SomeOtherProperty == false)
            {
                this.IsHyperlinkProperty = true;
                return false;
            }

            this.IsHyperlinkProperty = false;
            return true;
        }

        public DelegateCommand<object> WhateverTheHyperlinkDoesCommand { get; set; }

} }

答案 1 :(得分:0)

超链接上没有TextBlock.Visibility的附加属性。将样式直接放在包含超链接的TextBlock中,并且应该解析可见性。

如果没有,则创建一个bool to visibility converter并在TextBlock上设置转换器以获得可见性;并将转换器绑定到CanExecuteTheCommand属性。

应该注意的是,如果未在CanExecuteTheCommand属性上引发Property Changed通知,则转换器将仅在第一次加载视图时进行评估;之后,它将变得陈旧。

答案 2 :(得分:0)

今天我花了很多时间看这个,直到我尝试这个都没有用。 基本上,解决方案是将文本块中的文本放在文本块中,然后使用BooleanToVisiblityConverter设置该可见性,因为当超链接被禁用时,内部TextBlock将被禁用。

<UserControl.Resources>
    <converters:BooleanToVisibiltyConverter x:Key="BooleanToVisibiltyConverter" />
</UserControl.Resources>

<TextBlock >
    <Hyperlink Command="{Binding EditDetailsCommand}">
        <TextBlock
            Visibility="{Binding Path=IsEnabled
                , RelativeSource={RelativeSource Self}
                , Mode=OneWay
                , Converter={StaticResource BooleanToVisibiltyConverter}}">
        Edit Details 
        </TextBlock>
    </Hyperlink>                  
</TextBlock >


public class BooleanToVisibiltyConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null)
            throw new ArgumentNullException("value"); 

        if (!(value is bool))
            throw new ArgumentException("Expected type of value must be boolean");

        if (parameter != null && !(parameter is Visibility))
            throw new ArgumentException("Expected type of parameter must be Visibility");

        Visibility falseVisibility = Visibility.Collapsed;

        if (parameter != null)
        {
            falseVisibility = (Visibility)parameter;

            if (falseVisibility == Visibility.Visible)
            {
                throw new ArgumentException("Cannot pass visible to expected false value parameter.");
            }
        }

        return (bool)value ? Visibility.Visible : falseVisibility;  
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null)
            throw new ArgumentNullException("value"); 

        if (!(value is Visibility))
            throw new ArgumentException("Expected type of value must be Visibility");

        if (value == null)
        {
            throw new ArgumentNullException("value"); 
        }

        Visibility v = (Visibility)value;

        return v == Visibility.Visible;
    }
}

答案 3 :(得分:0)

命名超链接也有效,并为您提供一些灵活性。此外,您可以使用内置的BooleanToVisibilityConverter

<UserControl.Resources>
    <BooleanToVisibilityConverterx:Key="BooleanToVisibilityConverter" />
</UserControl.Resources>

<TextBlock Visibility="{Binding Path=IsEnabled,
                                ElementName=Linky,
                                Mode=OneWay,
                                Converter={StaticResource BooleanToVisibilityConverter}}">>
    <Hyperlink x:Name="Linky" Command="{Binding EditDetailsCommand}">
        <Run Text="Edit Details"/>
    </Hyperlink>                  
</TextBlock >