@ShpriZZ

Есть ли аналог элемента «ItemsControl», но для одного элемента?

Предположим, у меня есть класс телефона с его стоимостью:
public class Phone 
{
    public int Price { get; set; }

    pulic Phone(int price) 
    { 
        Price = price; 
    }
}

И два-класса наследника:
public class Xiaomi : Phone { public Xiaomi(int price) : base(price) { }}
public class IPhone : Phone { public IPhone(int price) : base(price) { }}

Если бы я хотел вывести на экран коллекцию телефонов, я бы создал ObservableCollection во ViewModel окна:
public ObservableCollection<Phone> Phones{ get => _Phones; set => _Phones= value; }
private ObservableCollection<Phone> _Phones = new();

А на форме бы определил элемент ItemsControl:
<ItemsControl ItemsSource="{Binding Phones}">
    <ItemsControl.Resources>
        <DataTemplate DataType="{x:Type Xiaomi}">
            <TextBlock Text="Этот телефон Xiaomi стоит:"/>
            <TextBlock Text="{Binding Path=Price}"/>
        </DataTemplate>

         <DataTemplate DataType="{x:Type IPhone}">
            <TextBlock Text="Этот телефон IPhone стоит:"/>
            <TextBlock Text="{Binding Path=Price}"/>
        </DataTemplate>
    </ItemsControl.Resources>
</ItemsControl>


Так я мог бы отобразить в окне коллекцию из телефонов, но как мне отобразить один телефон?
Допустим в коде у меня есть:
public Phone Telephone { get => _Telephone; set => _Telephone; }
private Phone _Telephone = new Xiaomi();

Есть ли какой-то элемент, чтобы я мог вывести это на форму? Использовать ItemsControl и создавать коллекцию для одного элемента выглядит очень костыльно.

Кто-то говорил, что для этого можно использовать ContentControl, но как именно не пояснили, а в интернете информации нет.
  • Вопрос задан
  • 91 просмотр
Решения вопроса 1
@ShpriZZ Автор вопроса
Итак, я нашёл нормальное решение. Без костылей, без неэффективного кода. Так и знал, что элегантное решение есть. Старое решение выведу в комментарии, потому что жалко потерянного на его написание времени.

Для отображения объекта класса из ViewModel в зависимости от его типа используется элемент ContentPresenter. В xaml его использование выглядит примерно так:

<ContentPresenter Content="{Binding Telephone}">
        <ContentPresenter.Resources>
        <DataTemplate DataType="{x:Type cl:Xiaomi}">
            <Label Content="Это ксяоми!"/>
        </DataTemplate>
        <DataTemplate DataType="{x:Type cl:IPhone}">
            <Label Content="Ну а это не очень телефон такой..."/>
        </DataTemplate>
    </ContentPresenter.Resources>
</ContentPresenter>


P.s. Мне говорили про этот элемент, но я почему-то подумал про ElementControl, не знаю даже почему.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
firedragon
@firedragon
Senior .NET developer
Коллекция из одного элемента отобразит один элемент.
Впрочем можно и просто отдельную переменную создать
https://metanit.com/sharp/wpf/11.php

<StackPanel>
       <TextBlock Text="Этот телефон Xiaomi стоит:"/>
       <TextBlock Text="{Binding XiomiPrice}"/>
</StackPanel>


И да для понимания
https://docs.microsoft.com/ru-ru/dotnet/desktop/wp...

Любой элемент с ItemsSource прокручивает вашу коллекцию, передавая вашему шаблону единственный элемент, а внутри шаблона вы привязываетесь к данным по пути
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы