WPF: How to make styles in XAML conditional on a variable in your own C# code

前端 未结 2 1706
别跟我提以往
别跟我提以往 2020-12-22 01:54

WPF and XAML newbie here....

I need to tie a WPF Trigger or DataTrigger in XAML code into some C# code in a class other than the class of t

相关标签:
2条回答
  • 2020-12-22 02:12

    How to make styles in XAML conditional on a variable in your own C# code

    I recommend that you look into a CellTemplate Selector (GridViewColumn.CellTemplateSelector Property (System.Windows.Controls)) where you can do the selection logic in code behind.

    Rough Example

    Simply define the templates (4 but two shown) needed in the resource

    <Window.Resources>
        <DataTemplate x:Key="EquipTemplate">
    
            <TextBlock Margin="2" Text="Equip" Foreground="Green"/>
    
        </DataTemplate>
    
        <DataTemplate x:Key="EventTemplate">
    
            <TextBlock Margin="2" Text="Event" Foreground="Red"/>
    
       </DataTemplate>
    
        <DataTemplate x:Key="UserTemplate" ...
    
    </Window.Resources>
    

    Xaml template usage selector for the grid cell

    <DataGridTemplateColumn Header="My Event">
        <DataGridTemplateColumn.CellTemplateSelector>
            <local:SelectedReportTypeTemplateSelector
                EquipTemplate="{StaticResource EquipTemplate}"
                EventTemplate="{StaticResource EventTemplate}"
                User...
            />
        </DataGridTemplateColumn.CellTemplateSelector>
    </DataGridTemplateColumn>
    

    Code Behind

    public class MeetingTemplateSelector : DataTemplateSelector
        {
            public DataTemplate EquipTemplate { get; set; }
    
            public DataTemplate EventTemplate { get; set; }
    
            public DataTemplate UserTemplate { get; set; }
    
            protected override DataTemplate SelectTemplateCore(object item, 
                      DependencyObject container)
            {
               DataTemplate result;
    
               switch( ((ReportSettingsData) item).SelectedReport)
               {
                    case EquipSummary : result = EquipTemplate; break;
                    case EventSummary : result = EventTemplate; break;
                    case UserSummary ..
               }
    
              return result;
            }
        }
    

    Update

    As per the comment that the variety of choices makes the template suggestion grow to over 30 templates. One other way might be to extend the target class with operational properties in lieu of the triggered actions. For example say we need a red color shown, provide it on the instance and bind.

    public Partial MyClassInstance
    {
        public Brush ColorMeAs 
        {
             get { return this.IsValid ? BrushGreen  : BrushRed; }
        }
        ... other properties as such:
    }
    

    then bind as such

    Foreground="{Binding ColorMeAs}"
    

    Triggers

    Here is an example of a data trigger pulled from my archive:

    <Style x:Key="LabelStyle" TargetType="{x:Type Label}">
        <Setter Property="VerticalAlignment" Value="Top" />
        <Setter Property="Width" Value="80" />
        <Setter Property="Height" Value="28"/>
        <Style.Triggers>
            <DataTrigger Binding="{Binding Path=LoginInProcess}" Value="True">
                <Setter Property="IsEnabled" Value="False" />
            </DataTrigger>
            <DataTrigger Binding="{Binding Path=LoginInProcess}" Value="False">
                <Setter Property="IsEnabled" Value="True" />
            </DataTrigger>
        </Style.Triggers>
    </Style>
    
    0 讨论(0)
  • 2020-12-22 02:19

    Your C# code looks fine, and you already have the XML NameSpace declaration referencing your MyApplication namespace, so:

    You should just be able to access the enum value using the x:Static markup using the enum identifier as shown in this example (I like this example because it also shows how to use non-custom x:Static and how to do some tree traversal as well):

    <DataTemplate.Triggers>
      <MultiDataTrigger>
        <MultiDataTrigger.Conditions>
          <Condition Binding="{Binding IsMouseOver, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}}}" Value="True" />
          <Condition Binding="{Binding Type}" Value="{x:Static loc:AppProfileItemType.Custom}" />
        </MultiDataTrigger.Conditions>
        <MultiDataTrigger.Setters>
          <Setter TargetName="PART_Delete" Property="Visibility" Value="{x:Static Visibility.Visible}" />
        </MultiDataTrigger.Setters>
      </MultiDataTrigger>
    </DataTemplate.Triggers>
    

    In your case your Markup for your enum should be:

    Value="{x:Static my:SelectedReportType.DiagSummary}"

    0 讨论(0)
提交回复
热议问题