【问题标题】:Unable to locate DataContext of parent object无法定位父对象的 DataContext
【发布时间】:2018-02-06 01:09:10
【问题描述】:

我正在尝试制作一个 TabControl,其中填充了几个 UserControls,每个都有一个单独的 ViewModel。

我已经在我的 XAML 中这样声明它:

<TabControl Margin="10,10,10,40" ItemsSource="{Binding Test}">
    <TabControl.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Name}" FontSize="16" Padding="5"/>
        </DataTemplate>
    </TabControl.ItemTemplate>
</TabControl>

如您所见,我正在尝试通过位于其视图模型中的属性来获取选项卡的名称:

public class GeneralTabViewModel : INotifyPropertyChanged
{
    private string _name;
    public string Name
    {
        get { return _name; }
        set
        {
            _name = value;
            OnPropertyChanged();
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public GeneralTabViewModel()
    {
        Name = "Name";
    }

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

与包含TabControl 的窗口关联的视图模型声明如下:

public class SettingsViewModel
{
    public ObservableCollection<UserControl> Test { get; set; }

    public SettingsViewModel()
    {
        Test = new ObservableCollection<UserControl>
        {
            new GeneralTab(),
            new GeneralTab()
        };
    }
}

像这样构建程序会为 2 个选项卡生成一个空的 Header。

如何将TextBlockText 属性绑定到位于UserControl 的视图模型中的Name 属性?

如果我将ItemSource 类型从ObservableCollection&lt;UserControl&gt; 更改为ObservableCollection&lt;GeneralTabViewModel&gt;,我将能够访问该属性,但是我将如何将UserControl 可视化呢?

【问题讨论】:

  • 用户控件的共享代码。
  • 您的 GeneralTab 用户控件必须实现 Generaltabviewmodel。在那里绑定名称属性。
  • @GaurangDave 你是在暗示我的用户控件应该同时是一个视图模型和一个用户控件吗?
  • 如果我理解正确,那么您需要将用户控件放在 SettingsViewModel 的测试集合中的每个选项卡项中。您给定 xaml 代码中的 Binding SettingsViewModel 则无法访问 GeneralTabViewModel 的属性。您应该将 GeneralTab(用户控件)代码放在这里。
  • @GaurangDave UserControl 的代码隐藏中没有任何内容。

标签: c# wpf xaml mvvm data-binding


【解决方案1】:

在 SettingsViewModel 中有 UserControls 是错误的。它应该有一个 GeneralTabViewModels 的集合:

public class SettingsViewModel
{
    public ObservableCollection<GeneralTabViewModel> Test { get; }

    public SettingsViewModel()
    {
        Test = new ObservableCollection<GeneralTabViewModel>
        {
            new GeneralTabViewModel { Name = "Tab 1" },
            new GeneralTabViewModel { Name = "Tab 2" }
        };
    }
}

然后您将在 TabControl 的 ItemTemplate 中使用 UserControl:

<TabControl Margin="10,10,10,40" ItemsSource="{Binding Test}">
    <TabControl.ItemTemplate>
        <DataTemplate>
            <GeneralTab TabName="{Binding Name}"/>
        </DataTemplate>
    </TabControl.ItemTemplate>
</TabControl>

为了使其正常工作,GeneralTab 不显式设置其 DataContext 属性很重要。它可能看起来像这样:

<UserControl x:Class="YourNamespace.GeneralTab" ...>
    <Grid>
        <TextBlock FontSize="16" Padding="5"
                   Text="{Binding TabName,
                          RelativeSource={RelativeSource AncestorType=UserControl}}"/>
    </Grid>
</UserControl>

在其代码中包含此依赖属性:

public static readonly DependencyProperty TabNameProperty =
    DependencyProperty.Register(nameof(TabName), typeof(string), typeof(GeneralTab));

public string TabName
{
    get { return (string)GetValue(TabNameProperty); }
    set { SetValue(TabNameProperty, value); }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-22
    • 1970-01-01
    • 2012-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多