Подтвердить что ты не робот

Свяжите текстовый блок с двумя свойствами

У меня есть текстовый блок, привязанный к свойству в коллекции ItemsSource. Я хотел бы отобразить два свойства из этого класса в том же текстовом блоке, но, похоже, я могу выполнять только одну привязку за раз. В настоящее время у меня есть это:

Text="{Binding Title}"

но я хочу, чтобы я добавил другое свойство, поэтому теоретически это будет:

Text="{Binding Title - Author}" 

с выходом, похожим на "Шекспир - Ромео и Джульетта". Я попытался добавить запятую, другую привязку и другие вещи, но все они приводят к тому, что исключение вызывается (например, Неизвестный атрибут Text в элементе TextBlock).

Оба свойства поступают из одного класса, поэтому мне не нужно иметь два источника данных.

4b9b3361

Ответ 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>