在wpf中一起使用按钮和扩展器

时间:2011-04-01 14:57:16

标签: c# wpf mvvm expander

我正在为一家公司开展一个Gui项目,我们正在尝试使用扩展器和按钮创建一个导航系统。 导航窗格应该看起来像这样 按键 扩展   按键   按键 扩展   按键   按键 按钮

问题在于,如果我打开扩展器,如果按下按钮它就不会关闭,但是如果按下另一个扩展器它会关闭。

2 个答案:

答案 0 :(得分:0)

如果我理解正确,您需要在按下按钮时关闭扩展器。如何设置按钮的点击事件Expander.IsExpanded = false

(或者等效地,因为您标记了MVVM,将IsExpanded绑定到属性并让按钮的命令将该属性设置为false。)

答案 1 :(得分:0)

将多个按钮和扩展器组合在一起需要您同步所有控件 您需要所有按钮来关闭打开的扩展器,并让打开的扩展器关闭打开的扩展器。

您可以通过命名控件来轻松地从代码隐藏中执行此操作;但要实现这一点 使用MVVM(带绑定)的解决方案有点棘手,因为Expander IsExpanded属性不支持双向绑定。

关键是要实现Expander对其IsExpanded状态使用的转换器,如下所示:

IsExpanded="{Binding Path=IsButtonSelected, Converter={StaticResource expConv}}

每个按钮命令将IsButtonSelected标志设置为true,以关闭打开的Expander。 因为Expanders使用转换器,您可以使用ConvertBack方法从开放扩展器关闭打开的扩展器。

我已经提供了帮助您跟进的代码。

以下是包含3个按钮和2个扩展器的视图:

<Window x:Class="Expander.Views.MainView"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
  xmlns:Helpers="clr-namespace:Expander.Converters" 
  Title="Main Window" 
  Height="400" Width="800">
  <Window.Resources>
    <Helpers:ExpanderConverter  x:Key="expConv"/>
  </Window.Resources>
  <Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <Button Grid.Row="0" Grid.Column="0" Command="{Binding Path=ButtonSelected}" Content="Command 1"/>
    <Button Grid.Row="1" Grid.Column="0" Command="{Binding Path=ButtonSelected}" Content="Command 2"/>
    <Expander ExpandDirection="Down" 
              Grid.Row="2" Grid.Column="0" 
              IsExpanded="{Binding Path=IsButtonSelected, Converter={StaticResource expanderConv}}" 
              Header="Details">
        <StackPanel Orientation="Horizontal">
        <Label Content="Name"/>
        <TextBox Width="100" />
        </StackPanel>
    </Expander>
    <Button Grid.Row="3" Grid.Column="0" Command="{Binding Path=ButtonSelected}" Content="Command 3"/>
    <Expander ExpandDirection="Down" 
              Grid.Row="4" Grid.Column="0" 
              IsExpanded="{Binding Path=IsButtonSelected, Converter={StaticResource expanderConv}}" 
              Header="Details">
        <StackPanel Orientation="Horizontal">
            <Label Content="Address"/>
            <TextBox Width="100"/>
        </StackPanel>
    </Expander>
  </Grid>
</Window>

这是从扩展器调用的转换器:

using System;
using System.Globalization;
using System.Windows.Data;

namespace Expander.Converters
{
  [ValueConversion(typeof(object), typeof(bool))]
  public sealed class ExpanderConverter : IValueConverter
  {
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
      bool result = (bool)value;
      return !result;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
      bool result =(bool)value;
      return result;
    }
  }
}

这是ViewModel:
我没有包含基类ViewModelBase和Command代码,因为你标记了MVVM所以我假设你有自己的实现。

using System.Windows.Input;
using Expander.Commands;

namespace Expander.ViewModels
{
  public class MainViewModel : ViewModelBase
  {
    public MainViewModel()
    {
      ButtonSelected = new DelegateCommand<object>(OnButtonSelected, CanButtonSelected);
    }

    public ICommand ButtonSelected { get; set; }
    private void OnButtonSelected(object obj)
    {
      IsButtonSelected = true;
    }

    private bool CanButtonSelected(object obj)
    {
      return true;
    } 

    private bool _isButtonSelected = true;
    public bool IsButtonSelected
    {
      get
      {
        return _isButtonSelected;
      }
      set
      {
        _isButtonSelected = value;
        OnPropertyChanged("IsButtonSelected");
      }
    }
  }
}