简体   繁体   English

当我单击UserControl内部的按钮时,如何更改MainWindow的内容?

[英]How do I change content from my MainWindow when I click a button from inside my UserControl?

I just started learning MVVM and I want to know what the best practice would be when I want to change content from my MainWindow when I click a button from inside my UserControl. 我刚刚开始学习MVVM,当我想从UserControl内部单击按钮更改MainWindow的内容时,我想知道最佳实践是什么。

This is the UserControl which contains the buttons that I will be clicking. 这是UserControl,其中包含我将要单击的按钮。 When I click on the IconButtons this produces, I want to be able to change the MainGrid to a Grid containing the information from my IconModel. 当我单击生成的IconButton时,我希望能够将MainGrid更改为包含我的IconModel信息的网格。

For clarification, I would like the Grid to show the Icon's Name, Description, Username, Password, and have a button that would open up either a program or a website using Path. 为了澄清起见,我希望网格显示图标的名称,描述,用户名,密码,并具有一个使用Path可以打开程序或网站的按钮。 The Icon class is inside IconModel.cs which is posted below. Icon类位于下面发布的IconModel.cs中。

IconView.xaml IconView.xaml

    <UserControl x:Class="ProgramManager.Views.IconView"
             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" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:ProgramManager"
             xmlns:viewModel="clr-namespace:ProgramManager.ViewModel"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <UserControl.DataContext>
        <viewModel:IconViewModel/>
    </UserControl.DataContext>
    <ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
        <ItemsControl ItemsSource="{Binding Path = Icons}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Button Name="IconButton" Style="{StaticResource IconButtonStyle}" Content="{Binding Path = Initial, Mode = OneWay}" Click="Button_Click">
                        <Button.ToolTip>
                            <ToolTip Content="{Binding Path = Name, Mode = TwoWay}"/>
                        </Button.ToolTip>
                    </Button>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </ScrollViewer>
</UserControl>

MainWindow.xaml MainWindow.xaml

    <Window x:Class="ProgramManager.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ProgramManager"
        xmlns:views="clr-namespace:ProgramManager.Views"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="1*"/>
        </Grid.ColumnDefinitions>
        <Grid Name="MainGrid" Grid.Column="1">

        </Grid>
    </Grid>
</Window>

For reference, here are my IconModel and IconViewModel classes. 作为参考,这是我的IconModel和IconViewModel类。

IconModel.cs IconModel.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Xml.Serialization;

namespace ProgramManager.Model
{

    public class IconModel { }

    [XmlRoot(ElementName = "Icons", IsNullable = true, DataType = "string")]
    [XmlType(AnonymousType = true)]
    [XmlInclude(typeof(ProgramIcon))]
    [XmlInclude(typeof(WebsiteIcon))]
    public class Icon : IComparable<Icon>, IComparer<Icon>, INotifyPropertyChanged
    {
        private string name;
        private string description;
        private string path;
        private string username;
        private string password;

        [XmlElement("Name")]
        public string Name
        {
            get { return name; }
            set
            {
                if (name != value)
                {
                    name = value;
                    RaisePropertyChanged("Name");
                }
            }
        }

        [XmlElement("Description")]
        public string Description
        {
            get { return description; }
            set
            {
                if (description != value)
                {
                    description = value;
                    RaisePropertyChanged("Description");
                }
            }
        }

        [XmlElement("Path")]
        public string Path
        {
            get { return path; }
            set
            {
                if (path != value)
                {
                    path = value;
                    RaisePropertyChanged("Path");
                }
            }
        }

        [XmlElement("Username")]
        public string Username
        {
            get { return username; }
            set
            {
                if (username != value)
                {
                    username = value;
                    RaisePropertyChanged("Username");
                }
            }
        }

        [XmlElement("Password")]
        public string Password
        {
            get { return password; }
            set
            {
                if (password != value)
                {
                    password = value;
                    RaisePropertyChanged("Password");
                }
            }
        }

        public string Initial {
            get
            {
                return this.Name.Substring(0, 1).ToUpper();
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void RaisePropertyChanged(string property)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(property));
            }
        }

        public int Compare(Icon x, Icon y)
        {
            return (x.Equals(null) || y.Equals(null)) ? 0 : x.CompareTo(y);
        }

        public int CompareTo(Icon other)
        {
            return string.Compare(this.Name, other.Name);
        }
    }

    public class ProgramIcon : Icon { }
    public class WebsiteIcon : Icon { }
}

IconViewModel.cs IconViewModel.cs

using ProgramManager.Helpers;
using ProgramManager.Model;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;

namespace ProgramManager.ViewModel
{
    public class IconViewModel : INotifyPropertyChanged
    {
        private static readonly List<Icon> iconsList;
        private ObservableCollection<Icon> icons;
        public ObservableCollection<Icon> Icons
        {
            get { return icons; }
            set
            {
                if (icons != value)
                {
                    icons = value;
                    RaisePropertyChanged("Icons");
                }
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;

        private void RaisePropertyChanged(string property)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(property));
            }
        }

        public IconViewModel()
        {
            LoadIcons();
        }

        static IconViewModel()
        {
            if (!Directory.Exists(Constants.ResourcesDirectory))
            {
                Directory.CreateDirectory(Constants.ResourcesDirectory);
            }

            iconsList = XmlDataStorage.GetList<Icon>(Constants.IconsFilePath);
        }

        public void LoadIcons()
        {
            ObservableCollection<Icon> icons = new ObservableCollection<Icon>();

            foreach(var icon in iconsList)
            {
                icons.Add(icon);
            }

            Icons = icons;
        }

        public void AddIcon(Icon icon)
        {
            iconsList.Add(icon);
            iconsList.Sort();

            XmlDataStorage.SaveToXml(Constants.IconsFilePath, iconsList);

            LoadIcons();
        }
    }
}

I have tried accessing the IconButton in MainWindow from the IconView.xaml, but I can't seem to figure out how to do it. 我尝试从IconView.xaml访问MainWindow中的IconButton,但似乎无法弄清楚该如何做。

Any help is appreciated, thank you! 任何帮助表示赞赏,谢谢!

  1. You can access the main window like Application.Current.MainWindow . 您可以访问诸如Application.Current.MainWindow类的主窗口。

  2. For MVVM solution you can do somethig like (Take the idea, I didn't compiled this): 对于MVVM解决方案,您可以做一些类似的事情(采取主意,我没有对此进行编译):

inside MainWindow.xaml: 在MainWindow.xaml中:

<Label DataContext="{IconViewModel }" Content={Binding YourProperty}/>

I mean you can set the data context of the label to be the IconViewModel and the to bind the property from IconViewModel class. 我的意思是,您可以将标签的数据上下文设置为IconViewModel,并将其绑定到IconViewModel类的属性。

  1. third option is to create an event inside IconViewModel and when you click the button to invoke the event, and the mainwindow will subscribe to this event. 第三个选项是在IconViewModel内创建一个事件,然后单击按钮以调用该事件,主窗口将预订该事件。

为什么不将IconView.xaml更改为ContentTemplate?并且将IconButton绑定依赖项属性,以便可以在任何地方操作IconButton,包括MainWindow。

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

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