WPF绑定TabControl TabItem

时间:2017-11-08 17:44:31

标签: c# wpf xaml mvvm

我对WPF中的MVVM相对较新,并且已经尝试解决了几天的问题。我正在使用dragablz选项卡控件并绑定ItemsSource,这是一个Observable对象列表。 Tab Item的内容是UserControl;其datacontext为null。我已经创建了一个简单的设置来演示我遇到的问题:

模型/ ViewModel类:

public class Item
{
    public string Header { get; set; }
    public ItemContent Body { get; set; }
}

public class ItemContent
{
    public string Name { get; set; }
    public string Description { get; set; }
}

class MainWindowViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged([CallerMemberName]string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    public ObservableCollection<Item> Items { get; set; }       
}

主窗口XAML

<Window x:Class="WpfTestApplication.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:WpfTestApplication"
    xmlns:views="clr-namespace:WpfTestApplication.ViewModels"
    xmlns:dragablz="clr-namespace:Dragablz;assembly=Dragablz"
    xmlns:dockablz="clr-namespace:Dragablz.Dockablz;assembly=Dragablz"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
    <views:MainWindowViewModel />
</Window.DataContext>
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition />
    </Grid.RowDefinitions>
    <Button Name="btnAdd" Content="Add" Click="btnAdd_Click" />
    <dockablz:Layout Grid.Row="1">
        <dragablz:TabablzControl HeaderMemberPath="Header" ItemsSource="{Binding Items}" SelectedIndex="1">
            <dragablz:TabablzControl.ContentTemplate>
                <DataTemplate DataType="{x:Type views:Item}">
                    <local:TabItemControl />
                </DataTemplate>
            </dragablz:TabablzControl.ContentTemplate>
        </dragablz:TabablzControl>
    </dockablz:Layout>
</Grid>
</Window>

标签项XAML

<UserControl x:Class="WpfTestApplication.TabItemControl"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local="clr-namespace:WpfTestApplication"
         xmlns:views="clr-namespace:WpfTestApplication.ViewModels"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<UserControl.DataContext>
    <views:ItemContent />
</UserControl.DataContext>
<Grid>
    <TextBox Text="{Binding Body}" />
</Grid>
</UserControl>

和btnAdd_Click事件

请注意,我不会在实际代码中使用它,但这是一种快速而又脏的方式,可以动态添加标签项而无需添加命令。

    private void btnAdd_Click(object sender, RoutedEventArgs e)
    {
        ((ViewModels.MainWindowViewModel)DataContext).Items.Add(new ViewModels.Item() { Header = "New One", Body = new ViewModels.ItemContent() { Name = "This One" } });
    }

1 个答案:

答案 0 :(得分:1)

将在对原始问题的评论中回答我的问题。我将他的回答用于另一篇文章:https://stackoverflow.com/a/44729258/1228以执行以下操作。

我从UserControl中删除了这个:

<UserControl.DataContext>
    <views:ItemContent />
</UserControl.DataContext>

然后我在我的UserControl代码后面添加了一个名为Body的依赖项属性:

public static readonly DependencyProperty BodyProperty = 
DependencyProperty.Register("Body", 
                            typeof(ViewModels.ItemContent), 
                            typeof(TabItemControl), 
                            new PropertyMetadata(null));

public ViewModels.ItemContent Body
{
    get
    {
        return (ViewModels.ItemContent)GetValue(BodyProperty);
    }
    set
    {
        SetValue(BodyProperty, value);
    }
}

public string BodyText {
    get
    {
        return Body?.Name;
    }
    set
    {
        if (Body != null)
        {
            Body.Name = value;
        }
    }
}

我更新了我的MainWindow Tab控件ContentTemplate:

<dragablz:TabablzControl.ContentTemplate>
    <DataTemplate DataType="{x:Type views:ItemContent}">
        <local:TabItemControl Body="{Binding Body}" />
    </DataTemplate>
</dragablz:TabablzControl.ContentTemplate>

并将我的UserControl更改为使用BodyText属性作为TextBox的值:

<Grid x:Name="LayoutRoot">
    <TextBox Text="{Binding BodyText}" />
</Grid>