WPF: LineBreak включает / отключает динамически - PullRequest
1 голос
/ 15 июня 2010

Я хотел бы сделать элемент LineBreak внутри этого TextBlock контролируемым пользователем в настройках Включить / Отключить его там

<TextBlock Style="{StaticResource TextBlockStyle}" Width="130">
<TextBlock.Inlines>
    <Run Text="{Binding Path=Name}" FontWeight="Bold" Foreground="#FF2A4D9E" />
    <Run Text="{Binding Path=Price}" FontWeight="Bold" />

       <LineBreak  />

    <Run Text="{Binding Path=Quantity}" Foreground="#99000000" />
</TextBlock.Inlines>
</TextBlock>

Ответы [ 2 ]

1 голос
/ 16 июня 2010

Я не верю, что в FlowDocument есть какой-то способ сделать LineBreak не сломанным, кроме как вытащить его. Вы можете переключиться на использование макета WPF или использовать присоединенное свойство для переключения между LineBreak и пустым Run.

Использование макета WPF

Вы можете вместо этого использовать макет WPF. Примерно так:

<DataTemplate x:Key="Layout1">
  <DockPanel>
    <TextBlock Text="{Binding Name}" FontWeight="Bold" Foreground="#FF2A4D9E" />
    <TextBlock Text="{Binding Price}" FontWeight="Bold" />
    <TextBlock Text="{Binding Quantity}" Foreground="#99000000" />
  </DockPanel>
</DataTemplate>

<DataTemplate x:Key="Layout2">
  <DockPanel>
    <DockPanel DockPanel.Dock="Top">
      <TextBlock Text="{Binding Name}" FontWeight="Bold" Foreground="#FF2A4D9E" />
      <TextBlock Text="{Binding Price}" FontWeight="Bold" />
    </DockPanel>

    <TextBlock Text="{Binding Quantity}" Foreground="#99000000" />
  </DockPanel>
</DataTemplate>

Теперь вы можете легко переключаться между макетами, просто переключая DataTemplates.

Автоматическое удаление LineBreaks с помощью привязок

Если вы хотите «скрыть» LineBreak с помощью привязки, вы можете сделать это с помощью присоединенного свойства «BecomeLineBreak», которое при применении к пустому Run и установке в значение true удаляет его и заменяет на LineBreak.

Как магия, теперь у вас есть возможность написать:

<Run my:LineBreakSwitcher.BecomeLineBreak="{Binding SomeCondition}" />

И ваш Run превратится в LineBreak каждый раз, когда свойство SomeCondition имеет значение true.

Вот код:

public class LineBreakSwitcher : DependencyObject
{
  public static bool GetBecomeLineBreak(DependencyObject obj) { return (bool)obj.GetValue(BecomeLineBreakProperty); }
  public static void SetBecomeLineBreak(DependencyObject obj, bool value) { obj.SetValue(BecomeLineBreakProperty, value); }
  public static readonly DependencyProperty BecomeLineBreakProperty = DependencyProperty.RegisterAttached("BecomeLineBreak", typeof(bool), typeof(LineBreakSwitcher), new PropertyMetadata
  {
    PropertyChangedCallback = (obj, e) =>
      {
        var oldElement = (Inline)obj;
        var newElement = (bool)e.NewValue ? (Inline)new LineBreak() : new Run();
        newElement.SetBinding(BecomeLineBreakProperty, oldElement.GetBindingExpression(BecomeLineBreakProperty).ParentBindingBase);

        var parent = (Paragraph)oldElement.Parent;
        parent.Inlines.InsertBefore(oldElement, newElement);
        parent.Inlines.Remove(oldElement);
      }
  });

Как это работает: когда BecomeLineBreak становится истинным при запуске, создается новый LineBreak, копируется привязка BecomeLineBreak, LineBreak вставляется перед запуском, затем запуск удаляется. Когда BecomeLineBreak становится ложным, создается новый прогон, и весь процесс происходит в обратном порядке.

0 голосов
/ 21 июля 2011

Это то, что вы хотите (100% XAML):

<TextBlock Text="{Binding Text, ElementName=MyContainer}" 
            FontWeight="Bold" FontSize="14" Name="TextBlockA" />
<TextBlock Name="TextBlockB">
    <TextBlock.Style>
        <Style>
            <Setter Property="TextBlock.Visibility" Value="Visible"/> 
            <Style.Triggers> 
                <DataTrigger Binding="{Binding Path=Text.Length, 
                        ElementName=TextBlockC}" Value="0"> 
                    <Setter Property="TextBlock.Visibility" Value="Collapsed"/> 
                </DataTrigger> 
            </Style.Triggers> 
        </Style>
    </TextBlock.Style>
    <LineBreak />
</TextBlock>
<TextBlock Text="{Binding SubText, ElementName=MyContainer}" 
            FontWeight="Normal" FontSize="12" Name="TextBlockC" />
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...