Свяжите текстовый блок с двумя свойствами
У меня есть текстовый блок, привязанный к свойству в коллекции ItemsSource. Я хотел бы отобразить два свойства из этого класса в том же текстовом блоке, но, похоже, я могу выполнять только одну привязку за раз.
В настоящее время у меня есть это:
Text="{Binding Title}"
но я хочу, чтобы я добавил другое свойство, поэтому теоретически это будет:
Text="{Binding Title - Author}"
с выходом, похожим на "Шекспир - Ромео и Джульетта". Я попытался добавить запятую, другую привязку и другие вещи, но все они приводят к тому, что исключение вызывается (например, Неизвестный атрибут Text в элементе TextBlock).
Оба свойства поступают из одного класса, поэтому мне не нужно иметь два источника данных.
Ответы
Ответ 1
К сожалению, Silverlight не хватает нескольких частей, которые WPF может обрабатывать. Я бы, вероятно, пошел по пути использования конвертера значений, который вы можете передать классу, который содержит Title и Author, чтобы отформатировать текст.
Здесь код:
public class TitleAuthorConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (!(value is Book)) throw new NotSupportedException();
Book b = value as Book;
return b.Title + " - " + b.Author;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
public class Book
{
public string Title { get; set; }
public string Author { get; set; }
}
И некоторые XAML:
<Grid x:Name="LayoutRoot" Background="White">
<Grid.Resources>
<local:Book Title="Some Book" Author="Some Author" x:Key="MyBook"/>
<local:TitleAuthorConverter x:Key="Converter"/>
</Grid.Resources>
<TextBlock DataContext="{StaticResource MyBook}" Text="{Binding Converter={StaticResource Converter}}"/>
</Grid>
Недостатком этого способа является то, что вы не получите текст для обновления, если изменения свойств (т.е. вы реализуете INotifyPropertyChanged), поскольку поле привязано к классу.
Как было предложено в комментариях к этому вопросу, вы также можете создать третье свойство, которое их объединяет. Это будет связано с необходимостью использования многозвенных или конвертеров значений.
Ответ 2
Используйте этот. Он будет работать отлично.
<TextBlock>
<Run Text="{Binding Title}"></Run>
<Run Text=":"></Run>
<Run Text="{Binding Author}"></Run>
</TextBlock>
вывод будет таким,
OOPS: Balagurusamy
Ответ 3
Похоже, вам нужен MultiBinding.
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} - {1}">
<Binding Path="Title" />
<Binding Path="Author" />
</MultiBinding>
</TextBlock.Text>
Ответ 4
Я нашел пример проекта MultiBinding для Silverlight в сети, некоторые из них я считаю, просто Google. Если вы не можете найти его, сообщите мне, я пришлю вам тот, который мы используем.
Кто-нибудь знает, подходит ли к SL 5 многосвязывание? Вы также можете использовать третье свойство, просто не забудьте запустить его PropertyChanged
событие, когда когда-либо его составные части меняются, тогда привязка будет прекрасной.
Ответ 5
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} - {1}">
<Binding Path="Title" />
<Binding Path="Author" />
</MultiBinding>
Ответ 6
Если текст, который вы хотите отобразить в пользовательском интерфейсе, доступен только для чтения, вы можете попробовать переопределить ToString вашего объекта модели просмотра и вернуть объединенное значение.
return Titile + ":" + Автор;
Ответ 7
Очень простое решение будет иметь свойство в вашей модели ViewModel следующим образом:
public string TextblockDataProvider
{
get
{
return string.Format("{0} - {1}", Title, Author);
}
set { ; }
}
и привязать в xaml:
Text="{Binding TextblockDataProvider}"
Ответ 8
Вы можете использовать специальное расширение из CodeProject
Пример
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} {1}" >
<Binding Path="FirstName" />
<Binding Path="LastName" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>