将对象从MainWindow发送到UserControl

时间:2013-12-21 12:41:50

标签: c# .net wpf

我刚刚抓到了wpf,我希望这个问题很简单。

你将如何管理这样的情况

在ui wpf项目中,有MainWindow和两个用户控件。在默认操作中,我想显示要隐藏的usercontrol1和usercontrol2。这两个控件都应该可以访问存储库实例以管理进一步的工作。我应该在每个控件中添加依赖项属性来使用此存储库实例,还是应该创建viewmodel并使用viewmodel。

关于绑定

假设我想在MainControl listview中显示一些数据列表。请纠正我

MainWindow.xaml

 <my:MainControl x:Name="mainControl" Repository="{Binding}" />

MainWindow.xaml.cs

public MainWindow()
{
   InitializeComponent();
   ICarRepository repository = new CarRepository();
   DataContext = repository;
}

MainControl.xaml.cs

public static readonly DependencyProperty RepositoryProperty = DependencyProperty.Register(
            "Repository",
            typeof(ICarRepository),
            typeof(MainControl),
            new PropertyMetadata(null));

        public ICarRepository Repository
        {
            get { return (ICarRepository)GetValue(RepositoryProperty); }
            set { SetValue(RepositoryProperty, value); }
        }

public MainControl() 
{
    InitializeComponent();
    DataContext = Repository.CountData();
}

MainControl.xaml

<Label Name="lblCountBooks" Content="{Binding}"/>   

据我所知这应该没问题,但我有一个主要障碍。我不知道如何将存储库实例从MainWindow传递到MainControl。我在这里做错了什么?

2 个答案:

答案 0 :(得分:1)

问题是您在MainControl的构造函数中设置MainControl的DataContext。实际上,这打破了外部绑定。

在构建控件之后,将从控件所有者绑定到控件。为了使绑定起作用,控件的所有者和控件都需要具有相同的DataContext。

从主控制的构造函数中删除绑定,并将其添加到根内容节点。这意味着该节点将拥有所有者的DataContext,允许控件所有者的绑定工作,而内容将具有UserControl的DataContext。

<UserControl>
    <Grid DataContext="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type this:UserControl2}}, Path=Repository}">
        <!-- content -->
    </Grid>
</UserControl>

为简洁起见,我删除了所有命名空间。

我希望这会有所帮助

答案 1 :(得分:1)

如您的评论中所述,RepositoryMainControl()构造函数中为空,直到构造函数完成并发生绑定为止。

相反,依赖于MainWindow中的绑定。还可以使用ICarRepository上的属性而不是CountData()方法。

<Label Name="lblCountBooks" Content="{Binding Path=DataCount}"/>

假设

public interface ICarRepository : INotifyPropertyChanged
{
    int DataCount { get; }
}

如果您的MainControl 必须明确接受Repository,则应回复正在设置的DependencyProperty并更新DataContext

public static readonly DependencyProperty RepositoryProperty =
        DependencyProperty.Register("Repository",
                                    typeof(ICarRepository),
                                    typeof(MainControl),
                                    new PropertyMetadata(OnRepositoryChanged));

private static void OnRepositoryChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    ICarRepository repository = e.NewValue as ICarRepository;
    ((MainControl)d).DataContext = repository;
}

MainWindow的绑定设置Repository的{​​{1}}属性时,MainControl会被回叫以通知您。这是更正OnRepositoryChanged

的正确时间