【问题标题】:How to show different font size for values depending on key in one row for wpf C#?如何根据 wpf C# 的一行中的键显示值的不同字体大小?
【发布时间】:2019-11-23 23:20:57
【问题描述】:

我有一个List<KeyValuePair<string, string>>

var output = new List<KeyValuePair<string, string>>(){
    new KeyValuePair<string, string>("string", "value1"),
    new KeyValuePair<string, string>("integer", "value2"),
    new KeyValuePair<string, string>("string", "value3"),
    new KeyValuePair<string, string>("decimal", "value4"),
};

我需要在一行中显示键和值,整数和小数的值应该有更大的字体和粗体。

它应该像这样显示:

[string:value1],[integer:value2],[string:value3],[decimal:value4]

【问题讨论】:

  • 您可能想查看 TextBlock 并运行。您可以使用它来拆分内容并使用不同的字体粗细。
  • 您可以使用IValueConverter 将您的string(字符串、整数、小数...)转换为FontWeight(例如Bold)。

标签: c# wpf xaml font-size


【解决方案1】:

我认为最简单和推荐的方法是使用ListView,其中ListView.ItemsPanel 是水平方向的StackPanel。要对齐项目并删除选择行为,将 Style 分配给 ListView.ItemContainerStyle 以禁用项目的命中测试并删除填充。
ListView.ItemTemplate 用于布局ListViewItem

这种方法仅适用于 XAML,在布局样式和行为方面提供了最佳灵活性。

查看模型

public class ViewModel : INotifyPropertyChanged
{
  public ViewModel()
  {
    this.Entries = new ObservableCollection<KeyValuePair<string, string>>()
    {
      new KeyValuePair<string, string>("string", "value1"),
      new KeyValuePair<string, string>("integer", "value2"),
      new KeyValuePair<string, string>("string", "value3"),
      new KeyValuePair<string, string>("decimal", "value4"),
    };
  }

  #region INotifyPropertyChanged

  public event PropertyChangedEventHandler PropertyChanged;
  protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
  {
    this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
  }

  #endregion

  private ObservableCollection<string> entries;
  public ObservableCollection<string> Entries
  {
    get => this.entries;
    set
    {
      this.entries = value;
      OnPropertyChanged();
    }
  }
}

MainWindow.xaml

<Window>
  <Window.DataContext>
    <local:ViewModel />
  </Window.DataContext>

  <Grid>
    <ListView ItemsSource="{Binding Entries}">

      <!-- Make the items align horizontally -->
      <ListView.ItemsPanel>
        <ItemsPanelTemplate>
          <StackPanel Orientation="Horizontal" />
        </ItemsPanelTemplate>
      </ListView.ItemsPanel>

      <ListView.ItemContainerStyle>
        <Style TargetType="ListViewItem">
          <Setter Property="Padding" Value="0" />
          <Setter Property="IsHitTestVisible" Value="False" />
        </Style>
      </ListView.ItemContainerStyle>

      <!-- Layout the item -->
      <ListView.ItemTemplate>
        <DataTemplate>             
          <StackPanel Orientation="Horizontal">
            <TextBlock x:Name="SeparatorTextBlock" Text="," />
            <TextBlock Text="{Binding Key, StringFormat=[{0}]:}" />
            <TextBlock Text="[" />
            <TextBlock x:Name="ValueTextBlock"
                       FontWeight="Bold"
                       Text="{Binding Value, StringFormat={}{0}}" />
            <TextBlock Text="]" />
          </StackPanel>

          <DataTemplate.Triggers>

            <!-- Set the FontWeight of the "ValueTextBlock" from bold to normal, if the Key has the value 'string' -->
            <DataTrigger Binding="{Binding Key}" Value="string">
              <Setter TargetName="ValueTextBlock" Property="FontWeight" Value="Normal"/>
            </DataTrigger>

            <!-- Remove the leading comma when the item is the first in the collection -->
            <DataTrigger Binding="{Binding RelativeSource={RelativeSource PreviousData}}" Value="{x:Null}">
              <Setter TargetName="SeparatorTextBlock" Property="Visibility" Value="Collapsed"/>
            </DataTrigger>
          </DataTemplate.Triggers>
        </DataTemplate>
      </ListView.ItemTemplate>
    </ListView>
  </Grid>
</Window>

或者,您可以使用ContentPresenter 作为占位符并使用EntryToTextBlockConverter IValueConverterContentPresenter.Content 绑定到Entries。布局调整必须在 C# 中完成,因此不太方便:

[ValueConversion(typeof(IEnumerable<KeyValuePair<string, string>>), typeof(TextBlock))]
public class EntriesToTextBlockConverter : IValueConverter
{
  public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
  {
    var result = string.Empty;
    if (value is IEnumerable<KeyValuePair<string, string>> entries)
    {
      var inlines = new List<Inline>();
      entries.ToList().ForEach(
        entry =>
        {
          inlines.Add(new Run("[" + entry.Key + "]:"));
          if (entry.Key.Equals("string", StringComparison.OrdinalIgnoreCase))
            inlines.Add(new Run("[" + entry.Value + "]"));
          else
          {
            inlines.Add(new Run("["));
            inlines.Add(new Bold(new Run("[" + entry.Value + "]")));
            inlines.Add(new Run("]"));
          }
          inlines.Add(new Run(","));
        });

      inlines.RemoveAt(inlines.Count - 1);
      var textBlock = new TextBlock();
      textBlock.Inlines.AddRange(inlines);
      return textBlock;
    }

    return Binding.DoNothing;
  }

  public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
  {
    throw new NotImplementedException();
  }
}

MainWindow.xaml

<Window>
  <Window.DataContext>
    <local:ViewModel />
  </Window.DataContext>
  <Window.Ressources>
    <local:EntriesToTextBlockConverter x:Key="EntriesToTextBlockConverter" />
  </Window.Ressources>

  <Grid>
    <ContentPresenter Content="{Binding Entries, Converter={StaticResource EntriesToTextBlockConverter}}">
  </Grid>
</Window>

【讨论】:

    【解决方案2】:

    如果您想在 C# 中完成所有操作并使用一个 TextBlock。试试这个 -

    创建一个函数 -

        private List<Run> GetRunItem(KeyValuePair<string, string> keyValue, bool addComma)
        {
            var inlines = new List<Run>();
            if (keyValue.Key.Equals("string", StringComparison.InvariantCultureIgnoreCase))
            {
                inlines.Add(new Run
                {
                    Text = $"[{keyValue.Key}:{keyValue.Value}]{(addComma ? "," : "")}"
                });
            }
            else
            {
                inlines.Add(new Run
                {
                    Text = $"[{keyValue.Key}:"
                });
                inlines.Add(new Run
                {
                    Text = $"{keyValue.Value}",
                    FontSize = 18,
                    FontWeight = FontWeights.Bold
                });
                inlines.Add(new Run
                {
                    Text = $"]{(addComma ? "," : "")}"
                });
            }
            return inlines;
        }
    

    并称它为 -

            for (int i = 0; i < output.Count; i++)
            {
                var runItems = GetRunItem(output[i], i < output.Count - 1);
                textBlock.Inlines.AddRange(runItems);
            }
    

    【讨论】:

      猜你喜欢
      • 2018-11-18
      • 2014-11-09
      • 2014-05-05
      • 2012-03-08
      • 2018-07-22
      • 1970-01-01
      • 2016-08-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多