Конкатенация строк вместо использования стека TextBlocks
Я хочу показать список объектов Customer в WPF ItemsControl. Я создал DataTemplate для этого:
<DataTemplate DataType="{x:Type myNameSpace:Customer}">
<StackPanel Orientation="Horizontal" Margin="10">
<CheckBox"></CheckBox>
<TextBlock Text="{Binding Path=Number}"></TextBlock>
<TextBlock Text=" - "></TextBlock>
<TextBlock Text="{Binding Path=Name}"></TextBlock>
</StackPanel>
</DataTemplate>
Так что я хочу в основном простой список (с флажками), который содержит NUMBER - NAME. Разве нет способа, которым я могу конкатрировать число и имя непосредственно в части Binding?
Ответы
Ответ 1
Существует свойство StringFormat (в .NET 3.5 SP1), которое вы, вероятно, можете использовать. И полезная обломочная оболочка WPF может найти здесь.
Если это не поможет, вы можете написать свой собственный ValueConverter или настраиваемое свойство для своего объекта.
Только что проверили, вы можете использовать StringFormat с многосвязным интерфейсом. В вашем случае код будет выглядеть примерно так:
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat=" {0} - {1}">
<Binding Path="Number"/>
<Binding Path="Name"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
Мне пришлось начать форматировать строку с пространством, иначе Visual Studio не будет строить, но я думаю, вы найдете способ обойти это:)
Изменить
Пространство необходимо в StringFormat, чтобы синтаксический анализатор не обрабатывал {0}
как фактическое связывание. Другие альтернативы:
<!-- use a space before the first format -->
<MultiBinding StringFormat=" {0} - {1}">
<!-- escape the formats -->
<MultiBinding StringFormat="\{0\} - \{1\}">
<!-- use {} before the first format -->
<MultiBinding StringFormat="{}{0} - {1}">
Ответ 2
Если вы хотите согласовать динамическое значение со статическим текстом, попробуйте следующее:
<TextBlock Text="{Binding IndividualSSN, StringFormat= '\{0\} (SSN)'}"/>
Дисплеи: 234-334-5566 (SSN)
Ответ 3
См. следующий пример, который я использовал в своем коде, используя класс Run:
<TextBlock x:Name="..." Width="..." Height="..."
<Run Text="Area="/>
<Run Text="{Binding ...}"/>
<Run Text="sq.mm"/>
<LineBreak/>
<Run Text="Min Diameter="/>
<Run Text="{Binding...}"/>
<LineBreak/>
<Run Text="Max Diameter="/>
<Run Text="{Binding...}"/>
</TextBlock >
Ответ 4
Вы также можете использовать прокси-соединение. Полезный материал, особенно если вы хотите добавить текстовое форматирование (цвета, шрифт и т.д.).
<TextBlock>
<something:BindableRun BoundText="{Binding Number}"/>
<Run Text=" - "/>
<something:BindableRun BoundText="{Binding Name}"/>
</TextBlock>
Вот оригинальный класс:
Ниже приведены некоторые дополнительные улучшения.
И это все в одном фрагменте кода:
public class BindableRun : Run
{
public static readonly DependencyProperty BoundTextProperty = DependencyProperty.Register("BoundText", typeof(string), typeof(BindableRun), new PropertyMetadata(new PropertyChangedCallback(BindableRun.onBoundTextChanged)));
private static void onBoundTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((Run)d).Text = (string)e.NewValue;
}
public String BoundText
{
get { return (string)GetValue(BoundTextProperty); }
set { SetValue(BoundTextProperty, value); }
}
public BindableRun()
: base()
{
Binding b = new Binding("DataContext");
b.RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, typeof(FrameworkElement), 1);
this.SetBinding(DataContextProperty, b);
}
}