0

Доброго времени суток!

У меня есть элемент TabControl, в котором я хочу реализовать кастомные Header, используя HeaderTemplate. Для этого я создал свой элемент:

<UserControl x:Class="iRestAdmin.CustomViews.TabHeader"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:customViews="clr-namespace:iRestAdmin.CustomViews">

    <UserControl.DataContext>
        <customViews:TabHeaderVm />
    </UserControl.DataContext>

    <StackPanel Margin="10">
        <TextBlock Text="{Binding F}"
                   HorizontalAlignment="Center" />

        <TextBlock Text="{Binding HeaderText}" />
    </StackPanel>
</UserControl>

И реализовал для него ViewModel:

public class TabHeaderVm
{
    public string F { get; set; }
    public string HeaderText { get; set; }
}

В самом классе View создал два поля для того, чтобы из Xaml присваивать значения TextBlock'ам:

public partial class TabHeader
{
    public string F
    {
        set => ((TabHeaderVm) DataContext).F = value;
    }

    public string HeaderText
    {
        set => ((TabHeaderVm) DataContext).HeaderText = value;
    }

    public TabHeader()
    {
        InitializeComponent();
    }
}

В результате сам TabControl стал выглядеть следующим образом:

<TabControl TabStripPlacement="Bottom">
    <TabItem>
        <TabItem.HeaderTemplate>
            <DataTemplate>
                <customViews:TabHeader F="F1" HeaderText="Вкладка 1"></customViews:TabHeader>
            </DataTemplate>
        </TabItem.HeaderTemplate>
    </TabItem>
</TabControl>

В результате всех манипуляций привязка к текста к `TextBlock'ам не идет. Как правильно реализовать то, что мне требуется, в рамках MVVM?

UPD: Реализовал INotifyPropertyChanged у `ViewModel' и все заработало. Сейчас хотелось бы просто узнать, насколько правильно я реализовал все это

mtrfnv
  • 737
  • Для контролов не создаются VM слои, у них создаются DependencyProperty, которые уже привязываются. – EvgeniyZ Feb 09 '20 at 12:11
  • @EvgeniyZ как тогда из Xaml указать DataContext? – mtrfnv Feb 09 '20 at 12:30
  • Не как. Повторюсь, у вас должны быть DependencyProperty, которые вы потом привязываете (<customViews:TabHeader F="F1" HeaderText="{Binding SomeProperty}">). Сам контрол должен должен отвечать лишь за отображение. Возьмите к примеру TextBlock, есть ли у него VM слой? А касательно DataContext, то его вы тоже должны установить только раз в приложение, все, дальше работаете с главной VM, заполняя ее чем надо. И кстати в XAML устанавливать не правильно. – EvgeniyZ Feb 09 '20 at 12:42
  • @EvgeniyZ получается, что в данном случае нет возможности реализовать все в рамках MVVM и одновременно обеспечить изменение в xaml коде при рефакторинге? – mtrfnv Feb 09 '20 at 13:49
  • Вы меня явно слышать не хотите. Я же вам сказал, что вам надо сделать контрол независимым от VM слоя, завязав все на DP. Дальше в основном View вы эти свойства привязываете к нужной VM как я показал выше. Любой View слой должен знать как можно меньше информации о ViewModel, он должен быть независим от нее. Также View слой не должен отвечать за создание VM слоя, чего вы нарушаете путем указания DataContext в XAML. – EvgeniyZ Feb 09 '20 at 14:19

0 Answers0