【问题标题】:C# / WPF Bind in TabControl ItemsSource to property in code behind of List itemC#/WPF 在 TabControl ItemsSource 中绑定到 List 项后面代码中的属性
【发布时间】:2019-10-25 02:37:51
【问题描述】:

在我的 ViewModel 中,我有一个 BindingList,其中包含我的视图,这些视图应该在我的 TabControl 中显示为选项卡。选项卡的文本在视图后面的代码中定义。我还定义了一个简单的测试类来测试完美运行的绑定。只有绑定到属性后面的代码不起作用。

我的 TabControl 的 Xaml 代码:

<TabControl ItemsSource="{Binding TabControlContentList}">
    <TabControl.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Path=DisplayName, FallbackValue=FallbackValue}" />
        </DataTemplate>
    </TabControl.ItemTemplate>
</TabControl>

它所绑定的BindingList:

void RaisePropertyChanged([CallerMemberName] string propertyName = "")
    => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));

public BindingList<object> TabControlContentList
{
    get => tabControlContentList;
    set
    {
        tabControlContentList = value;
        RaisePropertyChanged();
    }
}
private BindingList<object> tabControlContentList = new BindingList<object>();

测试类:

class ControlTest
{
    public string DisplayName { get; private set; } = "";

    public ControlTest(string name) => DisplayName = name;
}

AnalysisView.xaml.cs 后面的 Xaml 代码:

public partial class AnalysisView
{
    public string DisplayName { get; private set; } = "Analysis";

    public AnalysisView()
    {
        InitializeComponent();
    }
} 

在我的 ViewModel 中,我有以下代码:

public AnalysisView analysisView = new AnalysisView();
TabControlContentList.Clear();
TabControlContentList.Add(new ControlTest("Menu 1"));
TabControlContentList.Add(new ControlTest("Menu 2"));
TabControlContentList.Add(analysisView);
TabControlContentList.Add(new ControlTest("Menu 3"));
TabControlContentList.Add(new ControlTest("Menu 4"));

我的 TabControl 然后显示五个选项卡。前两个上面写着“Menu 1”和“Menu 2”,第三个写着“FallbackValue”,然后是“Menu 3”和“Menu 4”。

我不知道为什么 AnalysisView.xaml.cs 后面代码中的属性绑定不起作用。这可能是一般的 Wpf 事情吗?

【问题讨论】:

  • 这里有一些问题。首先,你不需要(实际上,不应该)在你的ViewModel 中有一个View 的实例。为这两者拥有两个不同的类并使用绑定的全部意义在于将它们解耦并消除依赖关系。通过做你正在做的事情,你正在增加依赖。
  • 接下来,List&lt;object&gt; 不是一个好主意,因为这会导致您在此处面临的许多类型问题。
  • @DavidP:AnalysisView 继承自什么类型?

标签: c# wpf xaml binding code-behind


【解决方案1】:

在我给出答案之前,我强烈建议您下载并学习如何使用Snoop for WPF,或使用 Visual Studio 内置的 XAML 运行时检查工具。这些允许您查看绑定、数据上下文等。

您的代码不起作用的主要原因是 UserControl 默认没有 DataContext

因此,像这样更新您的 AnalysisView 会使其 DataContext 指向自身:

public AnalysisView()
{
    InitializeComponent();
    DataContext = this;
}

但是,UserControl 中的 DataContext 不会像其他对象一样流入您的 DataTemplate。要使其正常工作,您需要像这样更改绑定:

<DataTemplate>
    <TextBlock Text="{Binding Path=DataContext.DisplayName, FallbackValue=ERROR!, RelativeSource={RelativeSource AncestorType={x:Type TabItem}}}" />
</DataTemplate>

像这样与UserControls 合作感觉就像是一种黑客行为。因此,您可能想寻找方法来设计您正在构建的任何应用程序。

此外,示例中的代码没有使用 INotifyPropertyChanged 作为属性,因此您不会收到任何更改通知。您可能想了解有关 MVVM 模式的更多信息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-09-18
    • 1970-01-01
    • 1970-01-01
    • 2015-11-07
    • 2011-02-15
    • 1970-01-01
    • 2020-06-14
    • 2011-02-25
    相关资源
    最近更新 更多