【问题标题】:XAML change TextBlock Margin property based on Rectangle's sizeXAML 根据 Rectangle 的大小更改 TextBlock Margin 属性
【发布时间】:2020-05-14 01:55:42
【问题描述】:

我正在尝试创建如下所示的内容:

它被设计为用于 VMIX 软件、视频广播目的的 XAML 标题。

我将从 GSheet 中获取大量数据,在 VMIX 中处理,并将这些数据分配给我的 TextBlock,例如“候选人”、“城市”和投票百分比。

从我想要增加/减少条形大小的百分比开始,我设法做到了其中的一部分。

但主要问题是让 % TextBlock 边距适合矩形的右侧。 任何人都知道我该怎么做?

我从来没有使用过 C# 编码,我有 C、C++ 和 JS 的背景,所以我花了一整天的时间寻找这个目的,但无法做到。

我看到了一些适合的绑定方法,但我无法使用它们。

此外,我正在为 Visual Studio 2017 开发 Blend,我不明白为什么按 F5 时我不能在其上运行一些简单的代码......这是另一个问题。

非常感谢您的帮助。

编辑:

到目前为止,我已经找到了一些新的解决方案,真正的 DIY 解决方案,但如果我找不到更好的解决方案,这是我的 lsat 解决方案:

我将为 1 个 ProgressBar 提供 2 个 TextBlock(感谢 Chris)

<Grid Margin="0,0,-8,0">
    <TextBlock x:Name="Votes1" HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Top" Margin="{Binding Text, ElementName=MarginVotes1}" FontSize="72" Width="853" Height="188"><Run Text="6"/><Run Text="00"/></TextBlock>
    <ProgressBar HorizontalAlignment="Left" Height="79" Margin="171,503,0,0" VerticalAlignment="Top" Width="{Binding Path=Text, ElementName=Votes1}" Background="#FFEA4545"/>
    <TextBlock x:Name="MarginVotes1" HorizontalAlignment="Left" Margin="171,587,0,0" TextWrapping="Wrap" VerticalAlignment="Top" FontSize="72" Height="98" Width="550"><Run Text="8"/><Run Text="0"/><Run Text="0"/><Run Text=","/><Run Text="4"/><Run Text="9"/><Run Text="0"/><Run Text=",0,0"/> 
   </TextBlock>

所以这很好用,但我必须在我的“MarginVotes1”值是什么之前做好准备(在 GoogleSheet 中)。

最好直接在代码后面做这样的事情:

将 Votes1.Text 转换为 val 中的 Int STORE

将 x 设置为 val + DefaultMargin

在 MarginX 中将 x 转换为字符串 STORE

创建字符串 MarginVoteStr as MarginX + ",500, 0, 0"

将 Votes1.Margin 设置为 MarginVoteStr

【问题讨论】:

  • 如果是我,我建议只设置实际的progressBar 控件样式模板,使其看起来像您想要的那样,而不是尝试从头开始创建。将使其更加通用,并花费更少的精力来实现目标。
  • 非常感谢克里斯的回答!它看起来像是一个需要照顾的解决方案。因此我必须测试它是否可以在广播软件中解释。此外,我不知道如何设置它的大小以及我的初始目标是自动设置文本边距。你对此有什么想法吗?
  • 请发布您的 Xaml。这将有助于了解您目前如何使上述工作到目前为止。
  • 嗨杰夫!以上还不行,这只是我目标的草稿。我正在为视觉 2017 使用混合,所以现在我在 C# 中有一行代码。但是我明天会发送它,因为我现在不在办公室
  • 我已经编辑了我的问题,所以你可以看到代码

标签: c# wpf xaml blend


【解决方案1】:

欢迎使用 WPF。这是我整理的一些代码,您应该非常接近您的需要。

XAML:

<ItemsControl Grid.IsSharedSizeScope="True" ItemsSource="{Binding Candidates}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Grid HorizontalAlignment="Left">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition SharedSizeGroup="Candidate" Width="Auto"/>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition Width="Auto"/>
                </Grid.ColumnDefinitions>

                <TextBlock Text="{Binding Name}"/>
                <Rectangle Grid.Column="1" Height="10" Margin="5, 0" Width="{Binding BarWidth}" Fill="{Binding BarColor}"/>
                <TextBlock Grid.Column="2" Text="{Binding Percentage, StringFormat=P}"/>
            </Grid>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

C#:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        Candidates = new List<Candidate> { new Candidate { Name = "Joe", Percentage = .50, BarColor = Brushes.Green},
                                            new Candidate { Name = "Bob", Percentage = .30, BarColor = Brushes.Yellow},
                                            new Candidate { Name = "Sarah", Percentage = .20, BarColor = Brushes.Gray}};
    }
               
    public List<Candidate> Candidates
    {
        get { return (List<Candidate>)GetValue(CandidatesProperty); }
        set { SetValue(CandidatesProperty, value); }
    }
    public static readonly DependencyProperty CandidatesProperty =
        DependencyProperty.Register("Candidates", typeof(List<Candidate>), typeof(MainWindow));
}

public class Candidate
{
    public string Name { get; set; }
    public double Percentage { get; set; }
    public Brush BarColor { get; set; }

    //This is just shorter syntax for a readonly property.
    //The multiplier (200) should be whatever length you want a full bar to be
    public double BarWidth => Percentage * 200;
}

有几点需要注意:

ItemsControl 和 DataTemplate

当您需要在 WPF 中显示多个数据项时,尤其是在项目数量可变的情况下,您应该使用某种类型的 ItemsControl

ItemsControl 采用某种集合并使用DataTemplate 显示每个项目。 ItemsControl 为其源集合中的每个项目创建其ItemTemplate 的新实例。通过data bindings建立数据和视觉之间的链接。

布局

&lt;DataTemplate&gt; 标签之间的所有内容都是单个项目的视觉布局。

请注意,我没有使用 Margin 创建所需的布局。我没有以这种方式使用Margin,而是使用许多Panel 控件之一的WPF:Grid。使用Grid,您可以像定义表格一样定义行和列。

我的示例中的每个项目都是一个Grid,有 1 行和 3 列。构成项目的元素使用Grid.Column 属性放置在该网格中。每列都有Width="Auto",这意味着它将增长以适应里面的宽度。 IsSharedSizeScopeSharedSizeGroup 使每个单独项目的 Grids 在第一列中都具有相同的宽度。

Candidate

这是用于存储和表示正在显示的数据的类。请注意,属性名称与 DataTemplate 中的 {Binding ______} 值匹配。

我的示例主窗口有一个Candidate 对象的集合,这些对象存储在dependency property 中。此属性绑定到ItemsControlItemsSource

总体

我们的想法是使用您需要的任何数据项填充您的集合,并让ItemsControl 处理其余部分,从而保持项目的数据和视觉效果相对独立。即使是小的视觉方面,例如正确格式化百分比值以进行显示,也可以使用 DataTemplate 完成,而不是使用 C# 编写代码,如使用 StringFormat=P 所示。

【讨论】:

    猜你喜欢
    • 2016-04-11
    • 2018-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-17
    • 1970-01-01
    • 2018-11-18
    相关资源
    最近更新 更多