简体   繁体   English

从MainWindow在UserControl中调用事件

[英]Calling event in UserControl from MainWindow

I have a UserControl with a Button and a ListView. 我有一个带按钮和ListView的UserControl。

Model 模型

public class Item
{
    private string _name = string.Empty;

    public string Name
    {
        get
        {
            return _name;
        }
        set
        {
            _name = value;
        }
    }
}

ViewModel 视图模型

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

UserControl (XAML) 用户控件(XAML)

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

I then add this to my MainWindow like so 然后像这样将其添加到我的MainWindow中

 public partial class MainWindow : Window
{

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

    }
}

This works fine and when I click the "Add" button the name "Chris" gets added to the ListView. 这工作正常,当我单击“添加”按钮时,名称“克里斯”被添加到ListView中。

Now I add a button to MainView and bind its Command property to my ViewModel like so: 现在,我向MainView添加一个按钮,并将其Command属性绑定到我的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>

When I click this button in the MainWindow the command is sent to the ViewModel, the addItem event gets called, the name "Chris" gets added to the ItemCollection, but the ListView doesn't update. 当我在MainWindow中单击此按钮时,命令将发送到ViewModel,调用addItem事件,名称“ Chris”被添加到ItemCollection,但ListView不会更新。 What am I doing wrong? 我究竟做错了什么?

Is your ViewModel being set as the data context of another element somewhere else (either in XAML or code-behind). 是否将ViewModel设置为其他元素(在XAML或代码隐藏中)的另一个元素的数据上下文。

Where you're setting it as the data context against the button, that will instantiate a new instance of the view model, so any interaction with the instance the button has access to will not update across other instances. 在将其设置为按钮的数据上下文的地方,将实例化视图模型的新实例,因此与按钮有权访问的实例的任何交互都不会在其他实例之间更新。

The button will inherit the data context from ancestor elements (eg the window etc), so you shouldn't need to set it, but if you do need a separate data context for the button, then I'd recommend creating the instance of ViewModel as a resource and then just referencing that for the elements that need access to it. 该按钮将继承祖先元素(例如,窗口等)的数据上下文,因此您无需设置它,但是如果确实需要该按钮的单独数据上下文,那么我建议创建ViewModel的实例。作为资源,然后仅针对需要访问它的元素进行引用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM