更改用户对列表选择的控制
本文关键字:选择 控制 列表 用户 | 更新日期: 2023-09-27 17:59:07
我是WPF的新手,并试图在选择相应的listviewitem时动态显示用户控件。我已经看了以下问题
WPF:根据相应的ViewModels(MVVM)切换UserControls
使用WPF/MVVM 在运行时动态更改UserControl内容
动态用户控制更改-WPF
所有的问题都提到了MVVM,我不认为我在使用它,或者如果我在使用,那是在不知不觉中。
为了更好地解释我正在尝试做什么,我在左侧有一个列表视图的窗口,在右侧,我想根据列表中的哪个项目被选择来动态显示用户控件。
要在用户控件1和用户控件2之间进行选择,我需要向XAML添加什么?要更改用户控件,我需要在"选择时操作"代码中添加哪些代码。
窗口
<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文件为空。
您所需要做的就是处理ListView对象的SelectionChanged:
<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>
我还将你的根命名为Grid。下面是代码:
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会收集不需要的对象,您可以将这些控件添加为类的字段,并在构造函数中初始化它们:
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个UserControls,其中N是可变的,你可以创建包含所有控件的Dictionary:
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*/}
}
}
}