繁体   English   中英

WPF-使用ResourceDictionary定义通用样式DataTrigger取决于Binding值

[英]WPF - Using a ResourceDictionary to define a generic style DataTrigger depends on Binding value

首先,我将尝试描述我所需要的内容。

我有一个应用程序,它显示像这样的仪表板: Dashboard-with-KPI

在这些KPI的每一行上,当有一个valueProcessed时,我想查看:

aTitle:valueToProcess / valueProcessed [%]

但是当没有任何valueProcessed时,我需要这样做

aTitle:0 [n / a]

为了实现它,我使用了像这样的DataTrigger:

<StackPanel Grid.Column="1" Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Right">
    <StackPanel>
        <StackPanel.Style>
            <Style TargetType="StackPanel">
                <Setter Property="Visibility" Value="Visible" />
                <Style.Triggers>
                    <DataTrigger Binding="{Binding NbLocationToInstall}" Value="0">
                        <Setter Property="Visibility" Value="Hidden" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </StackPanel.Style>
        <TextBlock Style="{StaticResource TextBlock_Default_Dashboard}" Text="{Binding NbLocationInstalled}"/>
        <TextBlock Style="{StaticResource TextBlock_Default_Dashboard_NoSpace}" Text="/" />
        <TextBlock Style="{StaticResource TextBlock_Default_Dashboard}" Text="{Binding NbLocationToInstall}"/>
        <TextBlock Style="{StaticResource TextBlock_Default_Dashboard}" Text="{Binding PrLocationInstalled, StringFormat={}[{0:0.##} %]}" />
    </StackPanel>

    <StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
        <StackPanel.Style>
            <Style TargetType="StackPanel">
                <Setter Property="Visibility" Value="Hidden" />
                <Style.Triggers>
                    <DataTrigger Binding="{Binding NbLocationToInstall}" Value="1">
                        <Setter Property="Visibility" Value="Visible" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </StackPanel.Style>
        <TextBlock Style="{StaticResource TextBlock_Default_Dashboard}" Text="{Binding NbLocationToInstall}"/>
        <TextBlock Style="{StaticResource TextBlock_Default_Dashboard}" Text="[n/a]" />
    </StackPanel>
</StackPanel>

显示StackPanel取决于一个名为NbLocationToInstall的绑定值。

此解决方案有效,但是,我要显示很多KPI行,并且我不想重复此块(=> n行表示像这样的n个块,只是绑定值会改变)。

因此,我决定创建一个字典,在其中设置样式:

<UserControl.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="../Dictionary.xaml"/>
        </ResourceDictionary.MergedDictionaries>

        <Style x:Key="ValidTrigger" TargetType="StackPanel">
            <Setter Property="Visibility" Value="Visible" />
            <Style.Triggers>
                <DataTrigger Binding="{Binding NbLocationToInstall}" Value="0">
                    <Setter Property="Visibility" Value="Hidden" />
                </DataTrigger>
            </Style.Triggers>
        </Style>

        <Style x:Key="InvalidTrigger" TargetType="StackPanel">
            <Setter Property="Visibility" Value="Hidden" />
            <Style.Triggers>
                <DataTrigger Binding="{Binding NbLocationToInstall}" Value="1">
                    <Setter Property="Visibility" Value="Visible" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </ResourceDictionary>
</UserControl.Resources>

现在,我可以这样使用它:

<StackPanel Grid.Column="1" Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Right">
    <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Style="{StaticResource ValidTrigger}">
        <TextBlock Style="{StaticResource TextBlock_Default_Dashboard}" Text="{Binding NbLocationInstalled}"/>
        <TextBlock Style="{StaticResource TextBlock_Default_Dashboard_NoSpace}" Text="/" />
        <TextBlock Style="{StaticResource TextBlock_Default_Dashboard}" Text="{Binding NbLocationToInstall}"/>
        <TextBlock Style="{StaticResource TextBlock_Default_Dashboard}" Text="{Binding PrLocationInstalled, StringFormat={}[{0:0.##} %]}" />
    </StackPanel>

    <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Style="{StaticResource InvalidTrigger}">
        <TextBlock Style="{StaticResource TextBlock_Default_Dashboard}" Text="{Binding NbLocationToInstall}"/>
        <TextBlock Style="{StaticResource TextBlock_Default_Dashboard}" Text="[n/a]" />
    </StackPanel>
</StackPanel>

但是,如何更改DataTrigger样式ValidTrigger的绑定值? 对于在上下文中给出的此示例,这在这里是有效的,但是对于其他行,我想传递另一个绑定变量。 在那里,它是ResourceDictionary中定义的NbLocationToInstall

非常感谢您的帮助。

根据建议,我对代码进行了审查。

首先,这是XAML代码定义:

<UserControl.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="../Dictionary.xaml"/>
        </ResourceDictionary.MergedDictionaries>

        <Style x:Key="ValidTrigger" TargetType="StackPanel">
            <Setter Property="Visibility" Value="Visible" />
            <Style.Triggers>
                <DataTrigger Binding="{Binding ValueToProcess}" Value="0">
                    <Setter Property="Visibility" Value="Hidden" />
                </DataTrigger>
            </Style.Triggers>
        </Style>

        <Style x:Key="InvalidTrigger" TargetType="StackPanel">
            <Setter Property="Visibility" Value="Hidden" />
            <Style.Triggers>
                <DataTrigger Binding="{Binding ValueToProcess}" Value="0">
                    <Setter Property="Visibility" Value="Visible" />
                </DataTrigger>
            </Style.Triggers>
        </Style>

    </ResourceDictionary>
</UserControl.Resources>

<!-- Detailed Information -->
<GroupBox Header="{x:Static lang:Resource.DetailedInformation}" Grid.Column="0" Grid.Row="0" Margin="5" Style="{StaticResource GroupBox_Default_Dashboard}">

    <StackPanel>
        <UniformGrid HorizontalAlignment="Stretch" Columns="2">
            <TextBlock Style="{StaticResource TextBlock_Default}" HorizontalAlignment="left" Text="{x:Static lang:Resource.DeploymentTime}" />
            <TextBlock Style="{StaticResource TextBlock_Default}" HorizontalAlignment="Right">
                <TextBlock.Text>
                    <MultiBinding StringFormat="{}{0:00} h {1:00;00} min">
                        <Binding Path="Time.Hours" />
                        <Binding Path="Time.Minutes" />
                    </MultiBinding>
                </TextBlock.Text>
            </TextBlock>
        </UniformGrid>

        <ListBox ItemsSource="{Binding KPIs}" BorderBrush="Transparent" Background="Transparent" HorizontalContentAlignment="Stretch">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Grid Margin="0">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="1*" />
                            <ColumnDefinition Width="0.45" />
                        </Grid.ColumnDefinitions>

                        <TextBlock Style="{StaticResource TextBlock_Default}" HorizontalAlignment="Left" Text="{Binding Label}"/>

                        <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Style="{StaticResource ValidTrigger}">
                            <TextBlock Style="{StaticResource TextBlock_Default_Dashboard}" Text="{Binding ValueProcessed}"/>
                            <TextBlock Style="{StaticResource TextBlock_Default_Dashboard_NoSpace}" Text="/" />
                            <TextBlock Style="{StaticResource TextBlock_Default_Dashboard}" Text="{Binding ValueToProcess}"/>
                            <TextBlock Style="{StaticResource TextBlock_Default_Dashboard}" Text="{Binding ValueProcessed, StringFormat={}[{0:0.##} %]}" />
                        </StackPanel>

                        <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Style="{StaticResource InvalidTrigger}">
                            <TextBlock Style="{StaticResource TextBlock_Default_Dashboard}" Text="{Binding ValueToProcess}"/>
                            <TextBlock Style="{StaticResource TextBlock_Default_Dashboard}" Text="[n/a]" />
                        </StackPanel>
                    </Grid>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </StackPanel>
</GroupBox>

这是KPI模型:

/// <summary>
/// provide a container to display a simple KPI
/// </summary>
public class KPI
{
    // props
    public string Label             { get; private set; }
    public double ValueToProcess    { get; private set; }
    public double ValueProcessed    { get; private set; }
    public double Percentage        { get; private set; }

    // default ctor
    public KPI(string label, double valueToProcess, double valueProcessed)
    {
        this.Label          = label;
        this.ValueToProcess = valueToProcess;
        this.ValueProcessed = valueProcessed;
        this.Percentage     = (valueToProcess == 0) ? Double.NaN 
                                                    : ValueProcessed / ValueToProcess * 100;
    }
}

这是声明:

ObservableCollection<KPI> _KPIs;
public ObservableCollection<KPI> KPIs
{
    get { return _KPIs; }
    set
    {
        _KPIs = value;
        RaisePropertyChanged("KPIs");
    }
}

这是定义:

KPIs = new ObservableCollection<KPI>()
{
    { new KPI(Lang.Resource.Label1, 5, 0) },
    { new KPI(Lang.Resource.Label2, 0, 0) },
    { new KPI(Lang.Resource.Label3, 0, 0) }
};

而且它运作完美。

我希望它可以帮助其他人。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM