2009-08-20 2 views
0

У меня есть то, что я считал простым требованием, но мне трудно понять, как это сделать.Складной «список» связанных элементов в WPF

Я привязки к адресу (Line1, Line2, Line3, Line4, например)

То, что я хочу сделать, это дисплей

Line1 
Line2 
Line3 
Line4 

Но если строка пуста или нулевой, я хотел бы „коллапс“:

Line1 
Line3 
Line4 

Я попытался StackPanel с TextBlocks - но я не работал, как получить TextBlocks к „исчезнуть“, если они пусты.

<StackPanel> 
    <TextBlock Text="{Binding Line1}"></TextBlock> 
    <TextBlock Text="{Binding Line2}"></TextBlock> 
    <TextBlock Text="{Binding Line3}"></TextBlock> 
    <TextBlock Text="{Binding Line4}"></TextBlock> 
</StackPanel> 

Я также попытался MultiBinding, но я не могу работать, как получить строку в StringFormat.

<TextBlock> 
    <TextBlock.Text> 
     <!-- Doesn't work: "System.FormatException" --> 
     <MultiBinding StringFormat="{}{1}\n{2}\n{3}\n{4}"> 
      <Binding Path="Line1"/> 
      <Binding Path="Line2"/> 
      <Binding Path="Line3"/> 
      <Binding Path="Line4"/> 
     </MultiBinding> 
    </TextBlock.Text> 
</TextBlock> 

Любые идеи?

ответ

4

Это немного уродливое, но оно работает. Я определил стиль с триггером, который коллапсирует в TextBlock, если его текст является пустой строкой:

<StackPanel> 
    <StackPanel.Resources> 
     <Style TargetType="{x:Type TextBlock}"> 
      <Style.Triggers> 
       <DataTrigger 
        Binding="{Binding Text,RelativeSource={RelativeSource Self}}" 
        Value=""> 
        <Setter Property="Visibility" Value="Collapsed" /> 
       </DataTrigger> 
      </Style.Triggers> 
     </Style> 
    </StackPanel.Resources> 
    <TextBlock Text="{Binding Line1}" /> 
    <TextBlock Text="{Binding Line2}" /> 
    <TextBlock Text="{Binding Line3}" /> 
    <TextBlock Text="{Binding Line4}" /> 
</StackPanel> 
+0

Это ужасно, но я думаю, что предпочитаю, потому что я не хочу, чтобы мой класс беспокоился о том, как будут отображаться данные. – Benjol

+0

Кроме того, если вы 't хотите исключить любой глобальный стиль, применяемый к TextBlock, добавьте BasedOn = "{StaticResource {x: Type TextBlock}}" в вашу декларацию стиля (я думаю, что у меня все в порядке). –

+0

@Benjol: если вы используете MVVM, это становится намного более естественным. Это означает, что ваша VM беспокоится о том, как вещи отображаются, и для этого будет иметь свойство только для чтения. –

2

Было бы легче всего просто агрегировать все эти свойства в другое только для чтения того, что вы связывающиеся:

<TextBlock Text="{Binding Address}"/> 

Однако, вы можете также связать Visibility каждого TextBlock:

<TextBlock Text="{Binding Line1}" Visibility="{Binding Line1, Converter={StaticResource TextVisibilityConverter}}"/> 

TextVisibilityConverter вернет Visibility.Collapsed, если значение null или пустое.

+1

Это меня поражает, как вещи, которые я думаю, будут проще в WPF всегда оказывается сложным. К сожалению, обратное не всегда так :( – Benjol