【问题标题】:TabControl - ToggleButtons as TabSeletors (XAML-Only Logic)TabControl - 作为 TabSeletors 的切换按钮(仅 XAML 逻辑)
【发布时间】:2016-02-10 06:24:15
【问题描述】:

目前我有一组切换按钮。 我想根据选中的按钮显示我的 TabControl 的不同选项卡。基本上与选择不同选项卡时的行为相同。不确定我的需求是否是无稽之谈,但无论如何。我希望 SelectedTab 根据单击的按钮进行更改。此外,我的 ToggleButtons 是与 Togglebuttons 相结合的 RadioButtons(我只希望一次检查一个)。我想尝试仅在 XAML 中实现我的需求(如果可能的话)。

这是我的 XAML 的一部分:

<Window.Resources>
    <sys:Int32 x:Key="CurrentTab"></sys:Int32>
    <Style TargetType="RadioButton" BasedOn="{StaticResource {x:Type ToggleButton}}">
        <Style.Triggers>
            <Trigger Property="IsChecked" Value="True">
                <Setter Property="Background" Value="Aqua"></Setter>
            </Trigger>
        </Style.Triggers>
        <Setter Property="Background" Value="Transparent"></Setter>
    </Style>
</Window.Resources>

    <TabControl Grid.Row="1"
                Grid.Column="1"
                Grid.ColumnSpan="2"
                SelectedIndex="{StaticResource CurrentTab}">
        <TabItem Visibility="Collapsed"></TabItem>
        <TabItem Visibility="Collapsed"></TabItem>
    </TabControl>

我想的是类似 (pseudoCode):

<Setter Target="{StaticResource CurrentTab}" Value="{ButtonsToolTip}></Setter>

基本上,甚至可以在 XAML 中为变量赋值吗?如果可以的话 - 怎么做?

作为一个示例,说明我为什么以及我试图实现的目标类似于这个 GUI:

【问题讨论】:

  • 我认为这是不可能的,反正在 XAML 中也不可能。您可以将其更改为 DynamicResource,但这仍然需要一些 C# 来更改 CurrentTab 值。
  • @MikeEason 嗯好的。因此,假设我为(CheckChanged 或 sth.)的 ButtonsStyle 添加了一个 EventTrigger,并且在我的代码后面的命令中,我将为 CurrentTab 设置一个值。这会自动为我的 TabControls SelectedIndex 引发 propertyChanged 事件吗?
  • 根据您的描述,我仍然不能完全确定您想要完成什么,但听起来您可以在切换按钮上设置一个交互触发器,以根据您的 Tab 控件执行 ChangePropertyAction任何 ToggleButton 的 IsChecked
  • @ChrisW。好的,请稍等,我会尽量让我的问题更清楚。
  • @FeDe 您使用哪种方法将按钮命令绑定到 C# 代码? MVVM 还是代码隐藏?

标签: c# wpf xaml tabcontrol wpf-style


【解决方案1】:

仅在 XAML 中无法使用事件触发器更改 StaticResource 的值。这必须通过将 StaticResource 绑定到 ViewModel 的属性或使用后面的代码来完成。

【讨论】:

    【解决方案2】:
    1. 您不能使用 xaml 更改声明为资源的原始类型的值。但是您可以使用对象的属性来充当变量。例如;

      <sys:Int32 x:Key="IntKey">12</sys:Int32>
      

      不可使用 XAML 进行修改。但是,DictionaryEntry 的 Value 属性(如下所示)是可修改的,尽管 DEKey 和 int(IntKey) 一样,也是不可修改的。

      <coll:DictionaryEntry x:Key="DEKey" Key="TagKey" Value="100"/>
      

    如果我尝试通过 binding 更改 integer(IntKey) ,它将不允许。例如; &lt;TextBox Text="{Binding Mode=OneWay,Source={StaticResource IntKey}}"/&gt; ,模式必须是单向。不允许使用 TwoWay、OneWayToSource 值。

    但我会写

    <TextBox  Text="{Binding Value,Source={StaticResource DEKey}}"/> 
    

    并且任何文本框值都将在 DictionaryEntry(DEKey) 的值中更新。注意,双向绑定不起作用,因为 DictionaryEntry 不是 DependencyObject。但是您现在可以按照自己喜欢的方式更改变量(Value 属性)。但唯一需要注意的是:对 Value 属性的更改不会反映在有界控件中。

    1. 是的,您可以利用上述信息显示标签 w.r.t。具有下面给出的方法的单选按钮。为了使绑定在两种方式中都能正常工作,我们需要一个 DependencyObject 和一个 DependencyProperty,因此我们使用 FrameworkElement 及其 Tag 属性。

    此 Tag 属性现在可以模拟您的相关变量。

        <Window.Resources>
            <FrameworkElement x:Key="rbTagHolder" Tag="0"/>
        </Window.Resources>
        ...
        <ItemsControl x:Name="RadioButtonList">
            <ItemsControl.ItemTemplate>
               <DataTemplate>
                  <RadioButton Content="{Binding TabName}" Tag="{Binding TagValue}" GroupName="Choice">
                  <i:Interaction.Triggers>
                      <i:EventTrigger EventName="Click">
                        <ei:ChangePropertyAction TargetObject="{DynamicResource rbTagHolder}" PropertyName="Tag" Value="{Binding Tag, RelativeSource={RelativeSource Mode=FindAncestor, AncestorLevel=1, AncestorType={x:Type RadioButton} }}"/>
                      </i:EventTrigger>
                  </i:Interaction.Triggers>
                  </RadioButton>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                   <StackPanel Orientation="Horizontal"/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
        </ItemsControl>
        ...
        <TabControl x:Name="TabCtrl" SelectedIndex="{Binding Tag, Source={StaticResource rbTagHolder}}"> ... </TabControl>
    

    代码隐藏

    RadioButtonList.ItemsSource = new[] { new { TabName = "Tab1", TagValue = "0" }, new { TabName = "Tab2", TagValue = "1" },
                    new { TabName = "Tab3", TagValue = "2" }, new { TabName = "Tab4", TagValue = "3" }};
    

    以防万一您不知道如何使用混合行为。

    A.包括以下命名空间:

    xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" 
    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 
    

    B.添加对以下内容的引用:Microsoft.Expression.Interactions、System.Windows.Interactivity 在我的系统上,这些位于

    C:\Program Files (x86)\Microsoft SDKs\Expression\Blend.NETFramework\v4.0\Libraries

    【讨论】:

    • 不错的答案坦克很多。 :D
    • 我刚刚试了一下,效果和我想要的一样。如果我在 XAML 中为每个按钮设置标签,我可以在没有代码隐藏文件或 ViewModel 的情况下完成所有操作 - 就像我想要的那样。我希望你能得到很多积极的投票,因为这个答案很精彩,并且 100% 符合我的需求。非常感谢:P
    猜你喜欢
    • 2018-02-13
    • 2015-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多