【问题标题】:Textblock as Link conditionally文本块有条件地作为链接
【发布时间】:2018-01-26 12:20:53
【问题描述】:

我有一个带有文本属性的标签绑定到一个类:

 <TextBlock Visibility="Hidden" TextTrimming="WordEllipsis" Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" Text="{Binding DisplayText}" TextWrapping="Wrap" FontSize="10"></TextBlock>

如果DisplayText 是链接,则应使用超链接。我绑定的类还提供了Uri 和一个布尔值isLink。我尝试在Textblock 中放置一个Hyperlink 元素,并将其NavigateUri 设置为类中的Uri,但这对我不起作用。 有没有人对此有一个干净的解决方案?

【问题讨论】:

    标签: c# wpf xaml hyperlink


    【解决方案1】:

    您可以使用这两个控件并根据isLink 属性更改它们的可见性。

    <Grid>
        <TextBlock>
            <Hyperlink NavigateUri="{Binding Uri}"
                       RequestNavigate="Hyperlink_RequestNavigate">
                <TextBlock Text="{Binding DisplayText}"/>
            </Hyperlink>
            <TextBlock.Style>
                <Style TargetType="TextBlock">
                    <Setter Property="Visibility" Value="Visible"/>
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding IsLink}" Value="False">
                            <Setter Property="Visibility" Value="Collapsed"/>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </TextBlock.Style>
        </TextBlock>
        <TextBlock Text="{Binding DisplayText}">
            <TextBlock.Style>
                <Style TargetType="TextBlock">
                    <Setter Property="Visibility" Value="Visible"/>
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding IsLink}" Value="True">
                            <Setter Property="Visibility" Value="Collapsed"/>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </TextBlock.Style>
        </TextBlock>
    </Grid>
    

    在后面的代码中:

    private void Hyperlink_RequestNavigate(object sender, RequestNavigateEventArgs e)
    {
        System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo(e.Uri.AbsoluteUri));
        e.Handled = true;
    }
    

    【讨论】:

    • 如果 isLink 为假,链接的蓝色下划线仍然存在,即使 isLink 为真,两个 TextBlock 也会显示。它们位于列表框的数据模板中的事实不应该影响它,对吗? imgur.com/BpKfeIx
    • 其实,这正是问题所在。 ListBox 中每个项目的DataContextListBox.ItemsSource 列表中的相应元素。这就是绑定不起作用的原因,它绑定到列表项的 isLink,女巫没有 isLink 属性。我说清楚了吗?要解决此问题,请将绑定更改为 Binding="{Binding RelativeSource={RelativeSource AncestorType=ListBox}, Path=DataContext.isLink}"
    • 列表框数据源绑定到为每个项目提供“DisplayText”和“isLink”的类的 ObservableCollection。
    • 您是否尝试过更改绑定?当您将集合绑定到ItemsControlItemsSource 时,通过您的DataTemplate 创建的每个接口项都会将各自的集合项自动设置为DataContext。例如,假设您的 VM 类中有一个 ObservableCollection&lt;Point&gt; Points 属性。在这种情况下,如果将ItemsSource 属性绑定到Points 属性,则DataTemplateDataContext 将是一个Point,而不是VM 类。
    【解决方案2】:

    我觉得你可以根据属性绑定一个模板。

     <ContentControl>
                    <ContentControl.Style>
                        <Style TargetType="ContentControl">
                            <Style.Triggers>
                                <DataTrigger Binding="{Binding IsLink}" Value="True">
                                    <Setter Property="ContentTemplate"  >
                                        <Setter.Value>
                                            <DataTemplate>
                                                <TextBlock>
                                                     <Hyperlink  NavigateUri="{Binding DataContext.Url, RelativeSource={RelativeSource Mode=FindAncestor,      
                            AncestorType= ContentControl} }">
                                                        <TextBlock Text="{Binding DataContext.DisplayText, RelativeSource={RelativeSource Mode=FindAncestor,      
                            AncestorType=ContentControl} }"/>
                                                    </Hyperlink>
                                                </TextBlock>
                                            </DataTemplate>
                                        </Setter.Value>
                                    </Setter>
                                </DataTrigger>
                                <DataTrigger Binding="{Binding IsLink}" Value="False">
                                    <Setter Property="ContentTemplate" >
                                        <Setter.Value>
                                            <DataTemplate>
                                                <TextBlock Text="{Binding DataContext.DisplayText,RelativeSource={RelativeSource Mode=FindAncestor,      
                            AncestorType=ContentControl} }"/>
                                            </DataTemplate>
                                        </Setter.Value>
                                    </Setter>
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </ContentControl.Style>
                </ContentControl>
    

    【讨论】:

      猜你喜欢
      • 2010-10-19
      • 2011-12-09
      • 2019-11-19
      • 2018-01-19
      • 2016-09-10
      • 2018-10-13
      • 2014-02-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多