【问题标题】: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 应该可见。

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

【问题讨论】:

    标签: c# wpf xaml


    【解决方案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】:
    1. 第二个 UC 取决于第一个,因此您需要一个 Binding

    2. 写一个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;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2023-03-28
      • 2018-10-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多