更改用户对列表选择的控制 [英] Changing user control on list selection

查看:26
本文介绍了更改用户对列表选择的控制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚接触 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

动态用户控件更改 - WPF

所有问题都参考了我认为我没有使用过的 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆