![](/img/trans.png)
[英]How can I get inside event_Click from instance of UserControl that created dynamicly from Button?
[英]How do I change content from my MainWindow when I click a button from inside my UserControl?
我剛剛開始學習MVVM,當我想從UserControl內部單擊按鈕更改MainWindow的內容時,我想知道最佳實踐是什么。
這是UserControl,其中包含我將要單擊的按鈕。 當我單擊生成的IconButton時,我希望能夠將MainGrid更改為包含我的IconModel信息的網格。
為了澄清起見,我希望網格顯示圖標的名稱,描述,用戶名,密碼,並具有一個使用Path可以打開程序或網站的按鈕。 Icon類位於下面發布的IconModel.cs中。
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
<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>
作為參考,這是我的IconModel和IconViewModel類。
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
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();
}
}
}
我嘗試從IconView.xaml訪問MainWindow中的IconButton,但似乎無法弄清楚該如何做。
任何幫助表示贊賞,謝謝!
您可以訪問諸如Application.Current.MainWindow
類的主窗口。
對於MVVM解決方案,您可以做一些類似的事情(采取主意,我沒有對此進行編譯):
在MainWindow.xaml中:
<Label DataContext="{IconViewModel }" Content={Binding YourProperty}/>
我的意思是,您可以將標簽的數據上下文設置為IconViewModel,並將其綁定到IconViewModel類的屬性。
為什么不將IconView.xaml更改為ContentTemplate?並且將IconButton綁定依賴項屬性,以便可以在任何地方操作IconButton,包括MainWindow。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.