C# 从主窗口调用UserControl中的事件

C# 从主窗口调用UserControl中的事件,c#,listview,mvvm,user-controls,C#,Listview,Mvvm,User Controls,我有一个带有按钮和ListView的UserControl 模型 视图模型 public class ViewModel : NotifyProperty { private Command addCommand; public ICommand AddCommand { get { if (addCommand == null) addCommand = new Command(ad

我有一个带有按钮和ListView的UserControl

模型

视图模型

public class ViewModel : NotifyProperty
{
    private Command addCommand;
    public ICommand AddCommand
    {
        get
        {
            if (addCommand == null)
                addCommand = new Command(addItem);
            return addCommand;
        }
    }

    private ObservableCollection<Item> _itemCollection;

    public ViewModel()
    {

        ItemCollection = new ObservableCollection<Item>();
        Item newItem = new Item();
        newItem.Name = "Joe";
        ItemCollection.Add(newItem);
    }

    public ObservableCollection<Item> ItemCollection
    {
        get
        {
            return _itemCollection;
        }
        set
        {
            _itemCollection = value;
            OnPropertyChanged("ItemCollection");
        }
    }

    private void addItem(Object obj)
    {
        Item newItem = new Item();
        newItem.Name = "Chris";
        ItemCollection.Add(newItem);
    }
}
这很好,当我单击“添加”按钮时,名称“Chris”被添加到ListView中

现在,我向MainView添加了一个按钮,并将其命令属性绑定到我的ViewModel,如下所示:

<Grid>
    <DockPanel>
        <Button Width="100" Height="30" Content="Add" Command="{Binding AddCommand}" DockPanel.Dock="Top">
            <Button.DataContext>
                <local:ViewModel />
            </Button.DataContext>
        </Button>
        <ContentControl x:Name="mainContentControl" />
    </DockPanel>       
</Grid>


当我在主窗口中单击此按钮时,命令被发送到ViewModel,addItem事件被调用,名称“Chris”被添加到ItemCollection,但ListView不更新。我做错了什么?

您的ViewModel被设置为其他地方另一个元素的数据上下文(在XAML或代码隐藏中)

在将其设置为按钮的数据上下文时,将实例化视图模型的新实例,因此与按钮有权访问的实例的任何交互都不会跨其他实例更新


该按钮将从祖先元素(例如窗口等)继承数据上下文,因此您不需要设置它,但如果确实需要为该按钮创建单独的数据上下文,那么我建议创建
ViewModel
实例作为资源,然后仅为需要访问它的元素引用该实例。

Yes,我在UserControl XAML中将ViewModel设置为DataContext。我删除了它,并将其设置在MainWindow XAML的窗口元素中,它可以正常工作!您还可以在代码隐藏中这样设置:DataContext=newviewmodel();我想这两种方式都是一样的。现在我已经完成了,我应该可以从我添加到主窗口的其他用户控件访问ViewModel了,对吗?@Chris yep!只要UserControl(或任何其他元素)被放置在另一个元素中,它就会继承父元素的数据控件-此规则的例外是ListBox中的项模板等,它们会将其datacontext设置为它们所表示的绑定集合中的实际对象。
<UserControl.DataContext>
    <local:ViewModel />
</UserControl.DataContext>

<UserControl.Resources>
    <DataTemplate x:Key="ItemTemplate">
        <StackPanel Orientation="Vertical">
            <Label Content="{Binding Name}" />
        </StackPanel>
    </DataTemplate>
</UserControl.Resources>

<Grid>
    <DockPanel>
        <Button Width="100" Height="30" Content="Add" Command="{Binding AddCommand}" DockPanel.Dock="Top" />
        <ListView ItemTemplate="{StaticResource ItemTemplate}" ItemsSource="{Binding ItemCollection}" />
    </DockPanel>
</Grid>
 public partial class MainWindow : Window
{

    public MainWindow()
    {
        InitializeComponent();
        this.mainContentControl.Content = new ListControl();

    }
}
<Grid>
    <DockPanel>
        <Button Width="100" Height="30" Content="Add" Command="{Binding AddCommand}" DockPanel.Dock="Top">
            <Button.DataContext>
                <local:ViewModel />
            </Button.DataContext>
        </Button>
        <ContentControl x:Name="mainContentControl" />
    </DockPanel>       
</Grid>