更改用户对列表选择的控制 [英] Changing user control on list selection
问题描述
我刚接触 WPF 并尝试在选择相应的列表视图项时动态显示用户控件.我看了以下问题
I new to WPF and attempting to dynamical display a user control when a corresponding listviewitem is selected. I have looked at the following questions
WPF:根据相应的 ViewModels (MVVM) 切换 UserControls一个>
使用 WPF 在运行时动态更改 UserControl 内容/MVVM
所有问题都参考了我认为我没有使用过的 MVVM,或者如果我是在不知不觉中使用.
All of the questions reference MVVM which I don't think I am using, or if I am it is unknowingly.
为了更好地解释我想要做什么,我在左侧有一个带有列表视图的窗口,在右侧我想根据选择列表中的哪个项目动态显示用户控件.
To better explain what I am trying to do I have a window with a listview on the left side, on the right side I would like to dynamically display a user control depending on which item in the list is selected.
我需要向 XAML 添加什么才能在用户控件 1 和用户控件 2 之间进行选择?我需要将哪些代码添加到我的选择操作"代码中以更改用户控件.
What do I need to add to my XAML to select between User Control 1 and User Control 2? What code do I need to add to my "on selection action" code to change the user control.
窗户
<Window x:Class="Manager.ProfileWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
Title="Edit Profile" Height="500" Width="700">
<Grid Background="WhiteSmoke">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" MinWidth="150" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="3*" MinWidth="300" />
</Grid.ColumnDefinitions>
<DockPanel>
<Border DockPanel.Dock="Top" Height="30" Margin="2">
<Border.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF5476F8" Offset="0"/>
<GradientStop Color="#FF001C87" Offset="1"/>
</LinearGradientBrush>
</Border.Background>
<TextBlock HorizontalAlignment="Left" VerticalAlignment="Center"
Text=" Profile Settings" FontSize="16" FontWeight="Bold" Foreground="White" Grid.Row="1"/>
</Border>
<ListView Margin="2" x:Name="SettingsList" DockPanel.Dock="Top" ItemsSource="{Binding Settings}"></ListView>
</DockPanel>
<GridSplitter Grid.Column="1" Grid.Row="0" Width="2" HorizontalAlignment="Stretch" ResizeDirection="Columns"/>
</Grid>
</Window>
用户控制 1
<UserControl x:Class="Manager.SomeSettings"
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"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Border VerticalAlignment="Top" Height="30" Margin="2">
<Border.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF5476F8" Offset="0"/>
<GradientStop Color="#FF001C87" Offset="1"/>
</LinearGradientBrush>
</Border.Background>
<TextBlock HorizontalAlignment="Left" VerticalAlignment="Center"
Text="Some Settings" Padding="5,0,0,0" FontSize="16" FontWeight="Bold" Foreground="White" Grid.Row="1"/>
</Border>
</Grid>
</UserControl>
用户控制 2
<UserControl x:Class="Manager.LocationSettings"
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"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Border VerticalAlignment="Top" Height="30" Margin="2">
<Border.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF5476F8" Offset="0"/>
<GradientStop Color="#FF001C87" Offset="1"/>
</LinearGradientBrush>
</Border.Background>
<TextBlock HorizontalAlignment="Left" VerticalAlignment="Center"
Text="Location Settings" Padding="5,0,0,0" FontSize="16" FontWeight="Bold" Foreground="White" Grid.Row="1"/>
</Border>
</Grid>
</UserControl>
用户控件的 *.xaml.cs 文件是空的.
The *.xaml.cs files for the user controls are empty.
推荐答案
你需要做的就是处理你的 ListView 对象的 SelectionChanged:
All you need to do is to handle SelectionChanged of your ListView object:
<Window x:Class="Manager.ProfileWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
Title="Edit Profile" Height="500" Width="700">
<Grid Background="WhiteSmoke" Name="dgRoot">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" MinWidth="150" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="3*" MinWidth="300" />
</Grid.ColumnDefinitions>
<DockPanel>
<Border DockPanel.Dock="Top" Height="30" Margin="2">
<Border.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF5476F8" Offset="0"/>
<GradientStop Color="#FF001C87" Offset="1"/>
</LinearGradientBrush>
</Border.Background>
<TextBlock HorizontalAlignment="Left" VerticalAlignment="Center"
Text=" Profile Settings" FontSize="16" FontWeight="Bold" Foreground="White" Grid.Row="1"/>
</Border>
<ListView x:Name="SettingsList"
Margin="2"
DockPanel.Dock="Top"
ItemsSource="{Binding Settings}"
SelectionChanged="OnSelectionChanged"></ListView>
</DockPanel>
<GridSplitter Grid.Column="1" Grid.Row="0" Width="2" HorizontalAlignment="Stretch" ResizeDirection="Columns"/>
</Grid>
我还为您的根网格命名.这是背后的代码:
I've also named your root Grid. And here's code behind:
private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
dgRoot.Children.Clear();
UserControl control = null;
if (<your_condition>)
{
control = new UserControl1();
}
else
{
control = new UserControl2();
}
control.SetValue(Grid.ColumnProperty, 2);
this.dgRoot.Children.Add(control);
}
添加:如果您不确定 GC 会收集不需要的对象,您可以将此控件添加为类的字段并在构造函数中初始化它们:
Addition: You can add this controls as fields of your class and initialize them in the constructor if you don't sure that GC will collect unneeded object:
public partial class ProfileWindow : Window
{
UserControl control1, control2;
// or if you want the exact types:
// UserControl1 control1;
// UserControl2 control2;
public ProfileWindow()
{
control1 = new UserControl1();
control2 = new UserControl2();
}
private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (<your_condition>) //then you want to add UserControl1 instance
{
if (!dgRoot.Children.Contains(control1))
{
dgRoot.Children.Clear();
control1.SetValue(Grid.ColumnProperty, 2);
this.dgRoot.Children.Add(control1);
}
}
else //else you want to add UserControl2 instance
{
if (!dgRoot.Children.Contains(control2))
{
dgRoot.Children.Clear();
control2.SetValue(Grid.ColumnProperty, 2);
this.dgRoot.Children.Add(control2);
}
}
}
}
另外 2 个:你可以走得更远.如果您有 N 个用户控件,其中 N 是变量,您可以创建包含所有控件的字典:
Additional 2: You could go further. If you will have N UserControls, where N is variable, you could create Dictionary that contains all your controls:
public partial class ProfileWindow : Window
{
private Dictionary<SettingsObject, UserControl> SettingsControls;
public ProfileWindow()
{
SettingsControls = new Dictionary<SettingsObject, UserControl>();
SettingsControls.Add(<your_setting>, new UserControl1());
SettingsControls.Add(<your_another_setting>, new UserControl2());
// and you can add any controls you want.
// in this example SettingsObject is type of items that are in the ListView.
// so, if your "Settings" object contains only strings, your dictionary can be Dictionary<string, UserControl>.
// if SettingsObject is custom object, you have to override GetHash() and Equals() methods for it
}
private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
var item = SettingsList.SelectedItem is SettingsObject;
if (item == null) return;
if (SettingsControls.ContainsKey(item) && !dgRoot.Children.Contains(SettingsControls[item]))
{
dgRoot.Children.Clear();
SettingsControls[item].SetValue(Grid.ColumnProperty, 2);
dgRoot.Children.Add(SettingsControls[item]);
}
else
{ /*handle it if you want*/}
}
}
}
这篇关于更改用户对列表选择的控制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!