在当前用户控件中单击按钮时显示不同的用户控件

Posted

技术标签:

【中文标题】在当前用户控件中单击按钮时显示不同的用户控件【英文标题】:Displaying a different user control when button is clicked in current user control 【发布时间】:2016-06-29 00:07:13 【问题描述】:

我目前有两个用户控件,即 UC1 和 UC2。我有一个主窗口。在应用程序启动时,用户可以看到 UC1。当用户点击 UC1 中的按钮时,UC1 应该消失,而 UC2 应该显示在同一个窗口中。我尝试了以下方法:

MainWindow.xaml

<Window x:Class="Test.MainWindow"
 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" xmlns:my="clr-namespace:Test" WindowState="Maximized"> 
<Grid>
    <my:UC1 />
    <my:UC2 Visibility="Collapsed"/>      
</Grid>

最初两个 UC 是同时可见的,所以我将 UC2 折叠了。现在我想在单击 UC1 中的按钮时再次使其可见。我无法从 UC1 访问 UC2 的可见性。

UC1.xaml.cs

  private void button2_click(object sender, MouseButtonEventArgs e)
    
        this.Visibility = System.Windows.Visibility.Collapsed;
        // What to write here?
    

编辑

对于 2 个控制器 UC1 和 UC2,使用 Tag 属性可以正常工作。现在我添加了另一个控制器 UC3,它只有在单击不同的按钮后才可见。

所以,最后我得到了 UC1、UC2 和 UC3,其中只有 UC1 是可见的。 UC1 有两个按钮,单击第一个按钮只有 UC2 应该可见,单击第二个按钮时只有 UC3 应该可见。

我无法绑定多个标签。有多标签转换器吗?

【问题讨论】:

【参考方案1】:
<Grid>
    <my:UC1 Name="UC1" />
    <my:UC2 Name="UC2" Visibility="Collapsed"/>      
</Grid>

private void button2_click(object sender, MouseButtonEventArgs e)

    this.UC1.Visibility = System.Windows.Visibility.Collapsed;
    this.UC2.Visibility = System.Windows.Visibility.Visible;

编辑:

刚刚意识到您的按钮位于 UC1 中。有很多方法可以做到这一点,但这可能是代码最少的一种方法。

<Grid>
    <my:UC2 Name="UC2" Visibility="Collapsed" />
    <my:UC1 Tag="Binding ElementName=UC2" />
</Grid>

private void button2_click(object sender, MouseButtonEventArgs e)

    this.Visibility = System.Windows.Visibility.Collapsed;

    var uc2 = this.Tag as UC2;
    if (uc2 != null)
        uc2.Visibility = System.Windows.Visibility.Visible;

这种方法最短,但其他人可能更难弄清楚你写了什么。

如果您想要一个好的方法,请在MainWindow 处进行,将UC2Visibility 绑定到UC1 的,并使用转换器。

<Grid>
    <Grid.Resources>
        <converters:VisibilityInversionConverter x:Key="VisibilityInversionConverter" />
    </Grid.Resources>

    <my:UC1 Name="UC1" />
    <my:UC2 Visibility="Binding ElementName=UC1, Path=Visibility, Converter=StaticResource VisibilityInversionConverter" />
</Grid>

【讨论】:

如果我现在希望新的用户控件 UC3 也依赖于 UC1,该怎么办?我可以添加多个标签绑定吗? @DeepikaDixit Nope... 这仅适用于这种情况。如果你想多次这样做,你应该使用AnjumSKhan's answer建议的转换器。他的解决方案确实有效 - 只需让 UC2 绑定到 UC1 的可见性(使用转换器)。当 UC1 可见时,UC2 不可见。单击 UC1 的按钮时,使事件自身(UC1)折叠。这将自动使 UC2 可见,因为它的可见性绑定到 UC1 的可见性。【参考方案2】:

    第二个 UC 取决于第一个,因此您需要一个 Binding

    写一个IValueConverter来切换Visibility,这样两个UC之间就没有依赖关系了。

    <Window.Resources>
       <local:ToggleVisConv x:Key="ConvKey"/>
    </Window.Resources>
    <Grid>
        <local:UserControl1 x:Name="UC1"/>
        <local:UserControl2 Visibility="Binding Visibility, ElementName=UC1, Converter=StaticResource ConvKey"/>
    </Grid>
    

转换器代码:

public class ToggleVisConv : IValueConverter


    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    
        Visibility v = (Visibility)value;
        if (v == Visibility.Collapsed)
            return Visibility.Visible;

        return Visibility.Collapsed;
    

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    
        throw new NotImplementedException();
    

【讨论】:

我只需要在单击按钮时切换可见性。还有另一个用户控制器 UC3 需要在单击不同按钮时进行切换。【参考方案3】:

编辑: 发布整个代码以使答案更清楚。而且我也没有任何例外。

MainWindow.xaml:

<Window x:Class="WpfApplication4.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:h="clr-namespace:WpfApplication4"
        Title="MainWindow"
        Width="525"
        Height="350">
    <Grid>
        <h:UC1 x:Name="Uc1" />
        <h:UC2 x:Name="Uc2" Visibility="Hidden" />
    </Grid>
</Window>

MainWindow.xaml.cs:

using System.Windows;

namespace WpfApplication4

    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    
        public MainWindow()
        
            InitializeComponent();
        
    

UC1.xaml:

<UserControl x:Class="WpfApplication4.UC1"
             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"
             d:DesignHeight="300"
             d:DesignWidth="300"
             mc:Ignorable="d">
    <Grid>
        <Ellipse Width="100"
                 Height="100"
                 Margin="65,113,0,0"
                 HorizontalAlignment="Left"
                 VerticalAlignment="Top"
                 Fill="CornflowerBlue"
                 Stroke="Black" />
        <Button Width="75"
                Margin="177,239,0,0"
                HorizontalAlignment="Left"
                VerticalAlignment="Top"
                Click="ButtonBase_OnClick"
                Content="ABCD" />
    </Grid>
</UserControl>

UC1.xaml.cs:

using System.Windows;
using System.Windows.Controls;

namespace WpfApplication4

    /// <summary>
    /// Interaction logic for UC_.xaml
    /// </summary>
    public partial class UC1 : UserControl
    
        public UC1()
        
            InitializeComponent();
        

        private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
        
            Window parentWindow = Application.Current.MainWindow;
            if (parentWindow.GetType() == typeof(MainWindow))
            
                (parentWindow as MainWindow).Uc1.Visibility = Visibility.Collapsed;
                (parentWindow as MainWindow).Uc2.Visibility = Visibility.Visible;
            
        
    

UC2.xaml:

<UserControl x:Class="WpfApplication4.UC2"
             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"
             d:DesignHeight="300"
             d:DesignWidth="300"
             mc:Ignorable="d">
    <Grid>
        <Ellipse Width="100"
                 Height="100"
                 Margin="169,22,0,0"
                 HorizontalAlignment="Left"
                 VerticalAlignment="Top"
                 Fill="Orange"
                 Stroke="Black" />
    </Grid>
</UserControl>

UC2.xaml.cs:

using System.Windows.Controls;

namespace WpfApplication4

    /// <summary>
    /// Interaction logic for UC2.xaml
    /// </summary>
    public partial class UC2 : UserControl
    
        public UC2()
        
            InitializeComponent();
        
    

【讨论】:

在 'parentWindow as MainWindow' 处给我空引用异常 @DeepikaDixit 您需要在 xaml 中设置 UC1UC2 的名称。 &lt;my:UC1 Name="UC1" /&gt;&lt;my:UC2 Name="UC2" Visibility="Collapsed"/&gt; 是的,我已经设置了名称。 我已经编辑过了。还添加了 xaml 代码。对我来说很好。如果还是不行。我将发布整个解决方案代码。 @ViVi 这正是我所做的。但没关系 Jai 发布的解决方案有效。我仍然会再试一次,因为它更简单,并尝试调试我的空异常。谢谢!【参考方案4】:

我使用依赖属性来做到这一点

Xaml:

     <StackPanel>
     <vm:UC1 GetUserControl2="Binding ElementName=usrUC2"  x:Name="usrUC1"/>
     <vm:UC2  x:Name="usrUC2"/>
     </StackPanel>

类:

public partial class UC1 : UserControl

    public UC1()
    
        InitializeComponent();
    

    public static readonly DependencyProperty GetUserControlProperty =
    DependencyProperty.Register("GetUserControl2", typeof(UserControl),
    typeof(UC1), null);

    public UserControl GetUserControl2
    
        get
        
            return (UserControl)GetValue(GetUserControlProperty);
        
        set
        
            SetValue(GetUserControlProperty, value);
        
    
    private void Button_Click(object sender, RoutedEventArgs e)
    
         GetUserControl2.Visibility = Visibility.Collapsed;
    

【讨论】:

以上是关于在当前用户控件中单击按钮时显示不同的用户控件的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET,在回发时显示加载消息

当用户单击侧导航中的按钮时显示数据 - html

需要在悬停或播放时显示 HTML5 视频控件

单击按钮时显示 2 个用户输入变量的结果

在按钮单击时在 Wfp 中使用用户控件

动态创建到 WPF 表单的用户控件上的按钮单击事件