【问题标题】:How can I recreate TextBlock style with multibinding in code?如何在代码中使用多重绑定重新创建 TextBlock 样式?
【发布时间】:2021-04-19 05:41:30
【问题描述】:

这是我为 WPF 应用程序提供的 TextBlock 的 XAML 代码。这适用于我当前的数据绑定。

<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="Black" FontSize="32" FontWeight="Bold">
                                <TextBlock.Style>
                                    <Style TargetType="TextBlock" BasedOn="{StaticResource InvisibleTextBlock}">
                                        <Style.Triggers>
                                            <DataTrigger Binding="{Binding MatchModel.TeamARightEnd}" Value="True">
                                                <Setter Property="Text">
                                                    <Setter.Value>
                                                        <MultiBinding StringFormat="{}{0} - {1}">
                                                            <Binding Path="TeamBScore"/>
                                                            <Binding Path="TeamAScore"/>
                                                        </MultiBinding>
                                                    </Setter.Value>
                                                </Setter>
                                            </DataTrigger>
                                            <DataTrigger Binding="{Binding MatchModel.TeamARightEnd}" Value="False">
                                                <Setter Property="Text">
                                                    <Setter.Value>
                                                        <MultiBinding StringFormat="{}{0} - {1}">
                                                            <Binding Path="TeamAScore"/>
                                                            <Binding Path="TeamBScore"/>
                                                        </MultiBinding>
                                                    </Setter.Value>
                                                </Setter>
                                            </DataTrigger>
                                        </Style.Triggers>
                                    </Style>
                                </TextBlock.Style>
                            </TextBlock>

现在我需要动态创建几个这样的文本块并将它们添加到StackPanel。我成功地重新创建了它:

TextBlock scoretextblock = new()
            {
                Name = "TextBlockScore" + i,
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center,
                Foreground = new SolidColorBrush(Colors.Black),
                FontSize = 32,
                FontWeight = FontWeights.Bold,
            };
            scoretextblock.Style = new()
            {
                TargetType = typeof(TextBlock),
                Triggers =
                {
                    new DataTrigger
                    {
                        Value = true,
                        Binding = new Binding("MatchModel.TeamARightEnd"),
                        Setters =
                        {
                            new Setter
                            {
                                Property = TextBlock.TextProperty,
                                Value = new Binding("TeamAScore") + " - " + new Binding("TeamBScore")
                            }
                        }
                    }
                }
            };

在执行过程中,我成功找到了上面的TextBlocks,并且可以更改datacontext。但是,显示的所需结果为空白。 有谁知道我做错了什么?或者有没有办法在 XAML 本身中动态地重新创建这些 TextBlock

谢谢!!

【问题讨论】:

  • 如果没有正确的minimal reproducible example,就不可能确定可能出了什么问题。但你似乎在做这一切都是错误的。您应该在 XAML 中使用所需的 &lt;TextBlock.../&gt; 声明一个 &lt;DataTemplate.../&gt; 元素,然后在 UI 布局的适当部分为该模板绑定一个视图模型。每当您在代码中实例化 UI 元素而不是仅在 XAML 中声明它们时,几乎可以肯定您犯了一个错误。
  • 啊好主意。我希望有某种模板可以轻松应用于动态创建的文本块
  • 等等。创建 DataTemplate 并将其应用于 TextBlock 样式不起作用。我收到“类型不兼容”错误。
  • 模板不适用于样式。 WPF 隐式地将它们用于绑定到为其声明模板的视图模型类型的特定实例的内容呈现器。您应该阅读 XAML 中的模板。例如,docs.microsoft.com/en-us/dotnet/desktop/wpf/data/…
  • 特别是这个部分:Styling and Templating an ItemsControl。您将使用 ItemsControl,它默认将 StackPanel 作为 ItemsPanel。使用您的 DataTemplate 作为其 ItemTemplate。

标签: .net wpf xaml data-binding


【解决方案1】:

SetterValue 应设置为MultiBinding,例如:

DataTrigger dataTrigger = new DataTrigger() { Value = true, Binding = new Binding("MatchModel.TeamARightEnd") };
MultiBinding multiBinding = new MultiBinding()
{
    StringFormat = "{0} - {1}"
};
multiBinding.Bindings.Add(new Binding("TeamAScore"));
multiBinding.Bindings.Add(new Binding("TeamBScore"));
dataTrigger.Setters.Add(new Setter() { Property = TextBlock.TextProperty, Value = multiBinding });

Style style = new Style() { TargetType = typeof(TextBlock) };
style.Triggers.Add(dataTrigger);

TextBlock scoretextblock = new TextBlock()
{
    Name = "TextBlockScore" + i,
    HorizontalAlignment = HorizontalAlignment.Center,
    VerticalAlignment = VerticalAlignment.Center,
    Foreground = new SolidColorBrush(Colors.Black),
    FontSize = 32,
    FontWeight = FontWeights.Bold,
    Style = Style
};

【讨论】:

  • 谢谢,但我已将所有内容移至 ItemsControl 并按照原始问题的 cmets 中的建议在那里使用 DataTemplates
  • 嗯,这回答了你原来的问题。请接受它以关闭线程。
【解决方案2】:

在尝试了几个建议之后,这是我的建议:

<ItemsControl x:Name="test" d:DataContext="{x:Static local:LiveScoreDesignDataContext.PreviousGamesSampleData}" ItemsSource="{Binding}" Foreground="Black" FontSize="32" FontWeight="Bold">
                                <ItemsControl.ItemsPanel>
                                    <ItemsPanelTemplate>
                                        <UniformGrid Rows="1"/>
                                    </ItemsPanelTemplate>
                                </ItemsControl.ItemsPanel>
                                <ItemsControl.ItemTemplate>
                                    <DataTemplate>
                                        <Grid>
                                            <TextBlock Grid.Column="0" HorizontalAlignment="Center">
                                                <TextBlock.Style>
                                                    <Style TargetType="TextBlock">
                                                        <Style.Triggers>
                                                            <DataTrigger Binding="{Binding TeamARightEnd}" Value="True">
                                                                <Setter Property="Text">
                                                                    <Setter.Value>
                                                                        <MultiBinding StringFormat="{}{0} - {1}">
                                                                            <Binding Path="TeamBScore"/>
                                                                            <Binding Path="TeamAScore"/>
                                                                        </MultiBinding>
                                                                    </Setter.Value>
                                                                </Setter>
                                                            </DataTrigger>
                                                            <DataTrigger Binding="{Binding TeamARightEnd}" Value="False">
                                                                <Setter Property="Text">
                                                                    <Setter.Value>
                                                                        <MultiBinding StringFormat="{}{0} - {1}">
                                                                            <Binding Path="TeamAScore"/>
                                                                            <Binding Path="TeamBScore"/>
                                                                        </MultiBinding>
                                                                    </Setter.Value>
                                                                </Setter>
                                                            </DataTrigger>
                                                        </Style.Triggers>
                                                    </Style>
                                                </TextBlock.Style>
                                            </TextBlock>
                                            <Border x:Name="brd" Grid.Column="0" Grid.ColumnSpan="3" BorderThickness="0,0,2,0" BorderBrush="Black"/>
                                        </Grid>
                                        <DataTemplate.Triggers>
                                            <DataTrigger Value="True">
                                                <DataTrigger.Binding>
                                                    <MultiBinding Converter="{StaticResource LastItemConverter}">
                                                        <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}" />
                                                        <Binding RelativeSource="{RelativeSource Self}"/>
                                                        <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}" Path="Items.Count"/>
                                                    </MultiBinding>
                                                </DataTrigger.Binding>
                                                <Setter TargetName="brd" Property="BorderThickness" Value="0" />
                                            </DataTrigger>
                                        </DataTemplate.Triggers>
                                    </DataTemplate>
                                </ItemsControl.ItemTemplate>
                            </ItemsControl>

它是这样的:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-04
    • 2014-11-28
    • 2013-12-19
    • 2021-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多