WPF TabControl DataBinding для другого класса

1

Я использую MahApps для моего первого проекта Wpf, а точнее tabControls. Я тестировал его на крошечном тестовом проекте. Он работал хорошо, пока я не попытался объединить свой код в моем проекте.

Вот пример моего кода:

public class Datas
{
    public ObservableCollection<string> titles { get; set; }

    public Datas()
    {
        init();
    }

    public void init()
    {
        titles = new ObservableCollection<string>()
        {
            "Title 1",
            "Title 2",
            "Title 3",
            "Title 4"
        };
    }
}

public partial class Window1 : MetroWindow
{
    private Datas datas;

    public Window1()
    {
        init();
    }

    private void init()
    {
        datas = new Datas();
        this.DataContext = this;
    }
}

И мой код Xaml:

<TabControl DataContext="{Binding Datas}">
    <TabControl.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding titles}"/>
        </DataTemplate>
    </TabControl.ItemTemplate>
    <TabControl.ContentTemplate>
        <DataTemplate>
            <TextBlock Text="Content" />
        </DataTemplate>
    </TabControl.ContentTemplate>
</TabControl>

До сих пор я искал несколько дней. Я нашел тему о DataBinding для другого класса, но, похоже, это не работает для меня. Не уверен, могу ли я использовать оба DataContexts в моем классе Window1, даже если бы я попытался что-то вроде привязки нескольких элементов управления к различным dataContexts.

Мне действительно нужно что-то подобное? Кажется, это больше, чем мне нужно, но я могу ошибаться. Итак, моя проблема в том, что я хотел бы иметь свои вкладки, названия которых принадлежат мне в моем списке, и ничего не отображает (при запуске ошибки нет).

Спасибо за вашу помощь, и, пожалуйста, не спешите с ответами, я все еще новичок в Wpf :)

Теги:
xaml
wpf
data-binding
mahapps.metro

2 ответа

1
Лучший ответ

Окно:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <TabControl ItemsSource="{Binding Titles}">
            <TabControl.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding}"/>
                </DataTemplate>
            </TabControl.ItemTemplate>
            <TabControl.ContentTemplate>
                <DataTemplate>
                    <TextBlock Text="Content" />
                </DataTemplate>
            </TabControl.ContentTemplate>
        </TabControl>
    </Grid>
</Window>

Код окна позади:

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            this.DataContext = new Datas();
            this.InitializeComponent();
        }
    }

    public class Datas
    {
        private ObservableCollection<String> titles;
        public ObservableCollection<String> Titles
        {
            get
            {
                if (this.titles == null)
                {
                    this.titles = new ObservableCollection<String>()
                    {
                        "Title 1",
                        "Title 2",
                        "Title 3",
                        "Title 4"
                    };
                }
                return this.titles;
            }
        }
    }

Некоторые советы:

  • Связывание работает только с общедоступными свойствами.

  • Не подвергайте ObservableCollection, если вы не собираетесь его изменять, вместо этого используйте IList (он легче).

  • В WPF, по крайней мере для свойств, ленивая инициализация более естественна, чем инициализация конструктора (см. Свойство Titles).

  • Взгляните на соглашения о капитализации.NET, предпочитайте использовать свойства Pascal Casing для свойств.

  • 0
    Woohoo! Оно работает ! Большое спасибо stackoverflow.com/users/1378699/raul-nuno , было так больно найти что-то подобное! Спасибо за вашу ссылку и ваши советы, я буду читать / следовать им как можно скорее, я не думал, что это было так "сложно" сделать это. Но что, если я хочу использовать более одного DataContext? И есть ли причина, по которой вы помещаете его выше метода InitializeComponent ()?
  • 0
    Добро пожаловать! Существует только один DataContext. Ваша ViewModel - это класс Datas, поместите туда все, что вы хотите представить в View. Причина размещения кода выше или ниже метода InitializeComponent хорошо объяснена здесь .
Показать ещё 1 комментарий
0

Установите ItemsSource TabControl и отмените общедоступные свойства Datas в вашем Window DataContext

 <TabControl ItemsSource="{Binding Datas.titles}">
   <TabControl.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding}"/>
            </DataTemplate>
        </TabControl.ItemTemplate>



 public partial class Window1 : MetroWindow
{


    public Window1()
    {
        init();
    }

    private void init()
    {
        Datas = new Datas();
        this.DataContext = this;
    }

     public Datas Datas{get;set;}
}
  • 0
    Спасибо за вашу помощь, но это не работает для меня, все равно ничего не показывает. Если я не ошибаюсь, ItemsSource может быть общедоступным свойством, как я и сделал, а затем <TextBlock Text = "{Binding title}" />. Я не думаю, что что-то пропустил в вашем коде ...
  • 0
    Нет, все еще не работает с вашим редактированием ...: /
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню