在XAML中将DataContext设置为当前的代码后台对象

5

我正在尝试将UserControl的DataContext设置为UserControl的代码后台类。从代码后台方面来说,这是非常容易做到的:

public partial class OHMDataPage : UserControl
{
    public StringList Stuff { get; set; }

    public OHMDataPage ()
    {
        InitializeComponent();

        DataContext = this;
    }
}

<UserControl 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"
    x:Class="LCDHardwareMonitor.Pages.OHMDataPage">

    <ScrollViewer>
        <ListBox ItemsSource="{Binding Stuff}" />
    </ScrollViewer>

</UserControl>

但是我如何仅从XAML方面和在UserControl级别上实现这一点呢?如果我这样做(并从code-behind中删除DataContext = this;),它可以适用于子节点:

<UserControl 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"
    x:Class="LCDHardwareMonitor.Pages.OHMDataPage">

    <ScrollViewer
        DataContext="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}">
        <ListBox ItemsSource="{Binding Stuff}" />
    </ScrollViewer>

</UserControl>

我真的希望能够理解如何在UserControl本身上执行此操作。 我预期这样可以起作用:

<UserControl 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"
    x:Class="LCDHardwareMonitor.Pages.OHMDataPage"
    DataContext="{Binding RelativeSource={RelativeSource Mode=Self}}">

    <ScrollViewer>
        <ListBox ItemsSource="{Binding Stuff}" />
    </ScrollViewer>

</UserControl>

但是它并没有。

嗯,看起来 DataContext="{Binding RelativeSource={RelativeSource Mode=Self}}" 在我的 MainWindow 上可以工作,但在这个 UserControl 上却不行。这很奇怪... - Adam
一个 ScrollViewer 里面放一个 ListBox 有什么意义? - fillobotto
刚刚开始学习。主要使用占位符内容。我看到ListBox上有一个HandlesScrolling属性。你问这个是因为ListBox已经实现了滚动条? - Adam
1
请注意,当将一个滚动组件放置在另一个滚动组件内部时要小心。 - fillobotto
1个回答

8
DataContext="{Binding Mode=OneWay, RelativeSource={RelativeSource Self}}"

应该可以正常工作。

但是,如果在调用InitializeComponent()之前未设置属性,则WPF绑定机制不知道您的属性值已更改。

简单来说:

// the binding should work
public StringList Stuff { get; set; }
public Constructor()
{
    Stuff = new StringList { "blah", "blah", "foo", "bar" };
    InitializeComponent();
}

// the binding won't work
public StringList Stuff { get; set; }
public Constructor()
{
    InitializeComponent();
    Stuff = new StringList { "blah", "blah", "foo", "bar" };
}

如果您正在使用字符串列表,请考虑改用 ObservableCollection。这将在添加或删除项目时通知 WPF 绑定机制。


当然那很简单…… 拍脑袋 谢谢。字符串列表仅用于测试,同时我在学习绳索。下一步是一个自定义树形结构,然后实现 INotifyCollectionChanged。 - Adam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接