2

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

xml:

<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();
}

如何设置文本块/超链接(或运行,如果需要)的样式,以便在 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

4 回答 4

2

I spent a lot of time looking at this today and nothing worked until I tried this. Basically the solution is to put the text inside the Hyperlink in a textblock and then set that's visibility using a BooleanToVisiblityConverter as the inner TextBlock becomes disabled when the hyperlink becomes disabled.

<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;
    }
}
于 2013-02-26T19:42:48.927 回答
0

超链接上没有 TextBlock.Visibility 的附加属性。将样式直接放在超链接的包含文本块中,这应该解决可见性。

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

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

于 2012-12-05T14:27:44.807 回答
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 >
于 2015-03-30T22:47:53.707 回答
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; }

} }

于 2012-12-05T13:46:37.617 回答