WPF DataContext从MainWindow继承到UserControl

时间:2017-06-22 07:25:45

标签: wpf xaml inheritance code-behind datacontext

我是WPF的新手,我有一个问题关注从MainWindow到UserControl的DataContext继承, 它将作为Tabpage附加到MainWindow的Tabcontrol。

我的代码摘要如下:

UserControlModel.cs

public class UserControlModel : INotifyPropertyChanged
{
    private string _name;
    public string Name
    {
        get { return _name; }
        set
        {
            if (_name != value)
            {
                _name = value;
                OnPropertyChanged("Name");
            }
        }
    }

    // Create the OnPropertyChanged method to raise the event
    protected void OnPropertyChanged(string name)
    {
        var handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(name));
        }
    }

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    #endregion
}

ViewModelLocator.cs

public class ViewModelLocator
{
    private UserControlModel UserControlModel { get; set; }

    public ObservableCollection<UserControlModel> Users { get; set; }

    public ViewModelLocator()
    {
        Users = new ObservableCollection<UserControlModel>
        {
            new UserControlModel { Name = "Albert" },
            new UserControlModel { Name = "Brian" }
        };
    }
}

MainWindow.xaml

<Window.Resources>
    <local:ViewModelLocator x:Key="VMLocator" />
</Window.Resources>

<Grid HorizontalAlignment="Left" Height="330" VerticalAlignment="Top" Width="592">
    <Grid HorizontalAlignment="Left" Height="45" Margin="0,330,-1,-45" VerticalAlignment="Top" Width="593">
        <Button Content="Button" HorizontalAlignment="Left" Margin="490,5,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/>
    </Grid>
    <TabControl HorizontalAlignment="Left" Height="330" VerticalAlignment="Top" Width="592" >
        <TabItem x:Name="UserControlTabItem" Header="User Control">
            <Grid x:Name="UserControlTabpage" Background="#FFE5E5E5">
                <local:UserControl VerticalAlignment="Top" DataContext="{Binding Users, Source={StaticResource VMLocator}}" />
            </Grid>
        </TabItem>
    </TabControl>
</Grid>

我创建一个ViewModelLocator实例,并将Users实例绑定到MainWindow.xaml中的UserControl。

MainWindow.xaml.cs

    public MainWindow()
    {
        InitializeComponent();
    }

UserControl.xaml

<Grid>
    <ListBox x:Name="lbUsers" DisplayMemberPath="???" HorizontalAlignment="Left" Height="250" Margin="30,27,0,0" VerticalAlignment="Top" Width="378"/>
</Grid>

UserControl.xaml.cs

    private ObservableCollection<UserControlModel> _users;

    public UserControl()
    {
        InitializeComponent();

        _users = ??? How to reference the Users instance created in MainWindow ???

        lbUsers.ItemsSource = _users;
    }

实际上,我想在ListBox中显示UserControlModel的Name属性。如果我是对的,UserControl实例是 使用Users实例作为MainWindow的DataContext继承。如何在代码隐藏中引用Users实例 UserControl.xaml.cs的用户?我已经检查过UserControl构造函数中的DataContext是否为null!怎么会?是什么 在代码隐藏中测试DataContext的正确方法/地点? 另外,如何在UserControl.xaml中设置ListBox的DisplayMemberPath属性。非常感谢。

2 个答案:

答案 0 :(得分:0)

我认为你可以在用户控件的XAML中设置或继承DataContext,就像这样

UserControl.xaml

<dialogs:Usercontrol DataContext="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=DataContext}" />

答案 1 :(得分:0)

您需要将ItemsSource的{​​{1}}属性绑定到源集合。由于ListBox的{​​{1}}是DataContext,您可以直接绑定到它:

UserControl

另外,请确保您未在​​代码中的任何其他地方明确设置ObservableCollection<UserControlModel>的{​​{1}}。

虽然您应该能够在加载<ListBox x:Name="lbUsers" ItemsSource="{Binding}" DisplayMemberPath="Name" ... /> 后引用DataContext:

DataContext

...无需在代码隐藏中设置UserControl的{​​{1}}属性。您应该通过在XAML中创建绑定来完成此操作。