在WPF中的画布上添加/删除用户控件 [英] Adding/removing User Controls on Canvas in WPF
问题描述
我创建了两个WPF用户控件,它们具有多个文本框,组合框和按钮。在wpf主窗口中,我创建了一个Canvas和一个其中包含两个列表项的列表框。我的要求是,如果选择第一个列表框项目,则第一个用户控件应添加到画布。如果我选择第二个列表框项目,则先前添加的用户控件应被隐藏,而第二个用户控件应被添加/显示。有人可以为此代码提供示例吗?
I have created two WPF user controls having multiple textboxes, comboboxes and buttons. In the main wpf window, I have created a Canvas and a listbox with two listitems in it. My requirement is, if select the first listbox item, the first user control should get added to canvas. If I select the second listbox item, the previously added user control should get hide, and second one should get added/showed. Can anyone provide an expample for this code?
下面是我编写的代码。我创建了两个用户控件。
Below is code I have writtent.I have created two user controls.
UserControl1.xaml
<UserControl x:Class="UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="210" Height="210" x:Name="UCntl1">
<Grid>
<StackPanel>
<GroupBox Header="Text Boxes">
<StackPanel Orientation="Horizontal">
<StackPanel>
<Label Margin="4" Height="21">TextBox1</Label>
<Label Margin="4" Height="21">TextBox2</Label>
<Label Margin="4" Height="21">TextBox3</Label>
</StackPanel>
<StackPanel>
<TextBox Width="100" Height="21" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="4">0.1</TextBox>
<TextBox Width="100" Height="21" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="4">0.2</TextBox>
<TextBox Width="100" Height="21" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="4">0.3</TextBox>
</StackPanel>
</StackPanel>
</GroupBox>
<GroupBox Header="Conbo Boxes">
<StackPanel Orientation="Horizontal">
<StackPanel>
<Label Margin="4" Height="21">ComboBox1</Label>
<Label Margin="4" Height="21">ComboBox2</Label>
<Label Margin="4" Height="21">ComboBox3</Label>
</StackPanel>
<StackPanel>
<ComboBox Width="100" Height="21" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="4">
<ComboBoxItem>Item AAA</ComboBoxItem>
</ComboBox>
<ComboBox Width="100" Height="21" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="4">
<ComboBoxItem>Item BBB</ComboBoxItem>
</ComboBox>
<ComboBox Width="100" Height="21" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="4">
<ComboBoxItem>Item CCC</ComboBoxItem>
</ComboBox>
</StackPanel>
</StackPanel>
</GroupBox>
</StackPanel>
</Grid>
</UserControl>
UserControl2.xaml
<UserControl x:Class="UserControl2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="210" Height="210" x:Name="UCntl2">
<Grid>
<StackPanel>
<GroupBox Header="Conbo Boxes">
<StackPanel Orientation="Horizontal">
<StackPanel>
<Label Margin="4" Height="21">ComboBox1</Label>
<Label Margin="4" Height="21">ComboBox2</Label>
<Label Margin="4" Height="21">ComboBox3</Label>
</StackPanel>
<StackPanel>
<ComboBox Width="100" Height="21" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="4"></ComboBox>
<ComboBox Width="100" Height="21" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="4"></ComboBox>
<ComboBox Width="100" Height="21" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="4"></ComboBox>
</StackPanel>
</StackPanel>
</GroupBox>
<GroupBox Header="Text Boxes">
<StackPanel Orientation="Horizontal">
<StackPanel>
<Label Margin="4" Height="21">TextBox1</Label>
<Label Margin="4" Height="21">TextBox2</Label>
<Label Margin="4" Height="21">TextBox3</Label>
</StackPanel>
<StackPanel>
<TextBox Width="100" Height="21" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="4"></TextBox>
<TextBox Width="100" Height="21" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="4"></TextBox>
<TextBox Width="100" Height="21" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="4"></TextBox>
</StackPanel>
</StackPanel>
</GroupBox>
</StackPanel>
</Grid>
Window1.xaml
<Window x:Class="Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="Auto" Width="Auto">
<Grid>
<StackPanel Orientation="Horizontal">
<Grid Margin="0,0,0,0" Width="Auto" Height="Auto" VerticalAlignment="Top">
<ListBox Margin="0,0,0,0" HorizontalAlignment="Left" Width="Auto" Height="Auto" VerticalAlignment="Top" BorderBrush="White">
<ListBoxItem Name="LstItem1" Selected="LstItem1_Selected">User Control 1</ListBoxItem>
<ListBoxItem Name="LstItem2" Selected="LstItem2_Selected">User Control 2</ListBoxItem>
</ListBox>
</Grid>
<Grid Width="10" Background="LightGray"></Grid>
<Grid Margin="0,0,0,0">
<Canvas Name="Canvas1" Width="210" Height="210" VerticalAlignment="Top">
</Canvas>
</Grid>
</StackPanel>
</Grid>
Widow1.xaml.vb
Class Window1
Private Sub LstItem1_Selected(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
Canvas1.Children.Clear()
Canvas1.Children.Add(New UserControl1)
End Sub
Private Sub LstItem2_Selected(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
Canvas1.Children.Clear()
Canvas1.Children.Add(New UserControl2)
End Sub
最终课程
问题
我在删除画布中的先前控件后添加了用户控件。因此,在将控件重新添加到画布时,将清除UserControls列表框中的所选值。有什么方法可以隐藏画布上的用户控件,而不是从画布上删除控件。
I have added the user control after removing the previous controls in the canvas. Because of this the selected values in the list boxes in UserControls are getting cleared while re-adding the control to the canvas. Is there any method to hide the usercontrols on the canvas, instead of removing the controls from canvas.
推荐答案
这应该可以帮助您入门。这与我在实际项目中的操作方式并不完全相同,但是足够接近。我希望有一个简单的方法可以将项目附加到此站点上的答案中。
This should get you started. It's not exactly how I'd do it in a real project, but close enough. I wish there was an easy way to attach projects to answers on this site.
最终结果如下:
App.xaml :
<Application x:Class="SO9735486.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:SO9735486.ViewModels"
xmlns:v="clr-namespace:SO9735486.Views"
StartupUri="MainWindow.xaml">
<Application.Resources>
<DataTemplate DataType="{x:Type vm:MainViewModel}">
<v:MainView/>
</DataTemplate>
<DataTemplate DataType="{x:Type vm:FirstContentViewModel}">
<v:FirstContentView/>
</DataTemplate>
<DataTemplate DataType="{x:Type vm:SecondContentViewModel}">
<v:SecondContentView/>
</DataTemplate>
</Application.Resources>
</Application>
MainWindow.xaml :
<Window x:Class="SO9735486.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow">
</Window>
MainWindow.xaml.cs :
namespace SO9735486
{
using System.Windows;
using SO9735486.ViewModels;
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.Content = new MainViewModel();
}
}
}
ViewModel.cs :
namespace SO9735486.ViewModels
{
using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Threading;
// http://kentb.blogspot.com/2009/04/mvvm-infrastructure-viewmodel.html
public abstract class ViewModel : INotifyPropertyChanged
{
private readonly Dispatcher _dispatcher;
protected ViewModel()
{
if (Application.Current != null)
{
_dispatcher = Application.Current.Dispatcher;
}
else
{
//this is useful for unit tests where there is no application running
_dispatcher = Dispatcher.CurrentDispatcher;
}
}
[field: NonSerialized]
public event PropertyChangedEventHandler PropertyChanged;
protected Dispatcher Dispatcher
{
get { return _dispatcher; }
}
protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
{
var handler = this.PropertyChanged;
if (handler != null)
{
handler(this, e);
}
}
protected void OnPropertyChanged(string propertyName)
{
OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
}
}
}
ContentViewModel.cs :
namespace SO9735486.ViewModels
{
public abstract class ContentViewModel : ViewModel
{
private readonly string displayName;
protected ContentViewModel(string displayName)
{
this.displayName = displayName;
}
public string DisplayName
{
get { return this.displayName; }
}
}
}
FirstContentViewModel。 cs :
namespace SO9735486.ViewModels
{
public sealed class FirstContentViewModel : ContentViewModel
{
private string name;
public FirstContentViewModel()
: base("First")
{
}
public string Name
{
get { return this.name; }
set
{
if (this.name != value)
{
this.name = value;
this.OnPropertyChanged("Name");
}
}
}
}
}
SecondContentViewModel.cs :
namespace SO9735486.ViewModels
{
public sealed class SecondContentViewModel : ContentViewModel
{
public SecondContentViewModel()
: base("Second")
{
}
}
}
MainViewModel.cs :
namespace SO9735486.ViewModels
{
using System.Collections.Generic;
using System.Linq;
public sealed class MainViewModel : ViewModel
{
private readonly ICollection<ContentViewModel> contentViewModels;
private ContentViewModel selectedContentViewModel;
public MainViewModel()
{
this.contentViewModels = new List<ContentViewModel>
{
new FirstContentViewModel(),
new SecondContentViewModel()
};
this.selectedContentViewModel = this.contentViewModels.First();
}
public ICollection<ContentViewModel> ContentViewModels
{
get { return this.contentViewModels; }
}
public ContentViewModel SelectedContentViewModel
{
get { return this.selectedContentViewModel; }
set
{
if (this.selectedContentViewModel != value)
{
this.selectedContentViewModel = value;
this.OnPropertyChanged("SelectedContentViewModel");
}
}
}
}
}
FirstContentView.xaml :
<UserControl x:Class="SO9735486.Views.FirstContentView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel>
<Label>First Content View</Label>
<TextBox Text="{Binding Name}"/>
</StackPanel>
</UserControl>
SecondContentView.xaml :
<UserControl x:Class="SO9735486.Views.SecondContentView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel>
<Label>Second content view</Label>
<Rectangle Fill="Blue" Width="100" Height="30"/>
</StackPanel>
</UserControl>
MainView.xaml :
<UserControl x:Class="SO9735486.Views.MainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<DockPanel>
<ComboBox DockPanel.Dock="Top" ItemsSource="{Binding ContentViewModels}" SelectedItem="{Binding SelectedContentViewModel}" DisplayMemberPath="DisplayName"/>
<ContentControl Content="{Binding SelectedContentViewModel}"/>
</DockPanel>
</UserControl>
这篇关于在WPF中的画布上添加/删除用户控件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!