【问题标题】:WPF TabControl DataBinding to another classWPF TabControl DataBinding 到另一个类
【发布时间】:2014-05-23 08:53:58
【问题描述】:

我在我的第一个 Wpf 项目中使用MahApps,更具体地说是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 to another class 的话题,但它似乎对我不起作用。不确定我是否可以在我的 Window1 类中使用这两个 DataContexts,即使我尝试了类似 binding multiple controls to different dataContexts 的东西。

我真的需要这样的东西吗?它似乎比我需要的要大,但我可能错了。所以,我的问题是我希望我的标签的标题是我列表中的那些,并且它不显示任何内容(但运行时没有错误)。

感谢您的帮助,请慢慢回答,我还是 Wpf 的新手 :)

【问题讨论】:

    标签: c# wpf xaml data-binding mahapps.metro


    【解决方案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>
    

    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;
                }
            }
        }
    

    一些建议:

    • 绑定仅适用于 public 属性。

    • 如果您不打算修改 ObservableCollection,请不要公开它,而是使用 IList(它更轻)。

    • 在 WPF 中,至少对于属性而言,惰性初始化比构造函数初始化更自然(参见 Titles 属性)。

    • 看看.NET capitalization conventions,更喜欢使用 Pascal Casing 作为属性。

    【讨论】:

    • 哇哦!有用 !非常感谢stackoverflow.com/users/1378699/raul-nuno 找到这样的东西真是太痛苦了!感谢您的链接和建议,我会尽快阅读/关注它们,我认为这样做并不那么“复杂”。但是如果我想使用多个 DataContext 怎么办?你有什么理由把它放在 InitializeComponent() 方法之上?
    • 不客气!只有一个 DataContext。您的 ViewModel 是 Datas 类,将您想要向 View 公开的所有内容放在那里。将代码放在 InitializeComponent 方法之上或之下的原因已经很好地解释了here
    • 好的,我明白了。我开始做类似的事情,但我必须重写我的代码......嗯,有趣的话题,我总是试图把它放在最后哈哈。我也会尝试找到一些关于绑定调试的东西,我一直想知道为什么它还没有实现。
    【解决方案2】:

    设置ItemsSourceTabControl 并在您的WindowDataContext 中定义公共属性Datas

     <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;}
    }
    

    【讨论】:

    • 感谢您的帮助,但它对我不起作用,它仍然没有显示任何内容。如果我没记错的话,ItemsSource 可能是公共属性,所以我做了,然后是 。我不认为我错过了您的代码中的某些内容...
    • 你能检查你的输出窗口是否有绑定错误吗?
    • 正如我所说,我是 WPF 新手。我快速检查了如何执行此操作,如果绑定失败,它应该向我返回警告。它不在这里
    • 正如 nit 所说,您必须检查输出窗口(在 Visual Studio 中)是否有包含“System.Windows.Data Error”的行。绑定错误不会显示在您的应用程序中,它们根本不起作用。
    猜你喜欢
    • 2011-02-09
    • 1970-01-01
    • 1970-01-01
    • 2013-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-13
    相关资源
    最近更新 更多