如何根据DataGridColumnHeader样式中的Button Visibility更新bool属性

时间:2016-02-11 06:19:37

标签: c# wpf xaml datagrid datatrigger

我已经为Target Type = DataGridColumnHeader实现了过滤器图标样式,并且我在DataGrid中附加了Style。

我的要求是,如果bool Property中的HasFilterIcon中的任何一个获得true,则将ViewModel button DataGridColumnHeader更新为visibility visible否则false

我的XAML风格是

<Style TargetType="{x:Type DataGridColumnHeader}" x:Key="DataGridElementStyle">
   <Setter Property="Template">
      <Setter.Value>
          <ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
              <Button Name="autofilter" Command="{Binding Path=DataContext.FilterPopUpCommand, 
                                  RelativeSource={RelativeSource Mode=FindAncestor, 
                                                  AncestorType={x:Type Window}}}">
                  <Button.CommandParameter>
                      <MultiBinding Converter="{StaticResource MultiValueConverterKey}">
                          <Binding RelativeSource="{ RelativeSource Mode=FindAncestor, 
                                                     AncestorType={x:Type cust:DataGrid}}" />
                          <Binding Path="Column" 
                                   RelativeSource="{RelativeSource Mode=TemplatedParent}" />
                      </MultiBinding>
                  </Button.CommandParameter>
              </Button>
              <ControlTemplate.Triggers>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="IsMouseOver" Value="True"></Condition>
                        </MultiTrigger.Conditions>
                        <Setter TargetName="autofilter" Property="Visibility" Value="Visible"/>
                    </MultiTrigger>
                </ControlTemplate.Triggers>
          </ControlTemplate>
      </Setter.Value>
   </Setter>
</Style>

我的XAML DataGrid是

<DataGrid Name="PassengerGrid" AutoGenerateColumns="False"  ColumnHeaderStyle="{StaticResource FilterDataGridColumnHeader}">
     <DataGridTextColumn Binding="{Binding CustomVisitTime}"  Header="Visit Time" CanUserSort="true" Width="90" ElementStyle="{StaticResource DataGridElementStyle}""/>
     <DataGridTextColumn Binding="{Binding PassengerName}"  Header="Passenger Name" CanUserSort="true" Width="90" ElementStyle="{StaticResource DataGridElementStyle}""/>
</DataGrid>

我需要更新的属性是

private bool _hasFilterIcon = false;
public bool HasFilterIcon
{
    get { return _hasFilterIcon; }
    set
    {
        _hasFilterIcon = value;
        OnPropertyChanged();
    }
}

如果任何列标题按钮获得Visibility Visible,那么我需要将HasFilterIcon的值更改为true,否则false。请帮助我。

  

注意:Style有N个按钮,在N中我必须检查   任何一个按钮都是Visible ......

1 个答案:

答案 0 :(得分:0)

使用BooleanToVisibilityConverter命名空间中的System.Window.Control。只需将其解析如下,并在绑定中使用(在页面/窗口资源中)。

<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />

绑定如下:(模式OneWayToSource反映属性)

Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}},Path=HasFilterIcon,Converter={StaticResource BooleanToVisibilityConverter},Mode=OneWayToSource}"

<强>更新

  

因为在XAML / WPF中没有干净的方法来执行此操作(只有干净的方法是创建单独的   用于分隔按钮可见性的属性

试一试

1.像这样创建你的财产:

private AllButtonVisibility visible = new AllButtonVisibility();

    public AllButtonVisibility Visible
    {
        get { return visible; }
        set 
        { 
            visible = value;
            RaiseChange("Visible");
        }
    }

    public class AllButtonVisibility
    {
        public bool AllButtonVisible { get; set; }
    }

<强> 2。示例XAML:

 <Window.Resources>
    <local:MyMultivalueConverter x:Key="MyMultivalueConverter" />
</Window.Resources>

<ContentControl Width="0">
        <ContentControl.Content>
            <MultiBinding Converter="{StaticResource MyMultivalueConverter}">
            <Binding ElementName="dataGrid" />
            <Binding Path="Visible"  />
             <Binding ElementName="dataGrid" Path="ActualHeight" />
            </MultiBinding>
        </ContentControl.Content>
    </ContentControl>
</StackPanel>

第3。转换器:

public class MyMultivalueConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        List<DataGridColumnHeader> columnHeaders = GetVisualChildCollection<DataGridColumnHeader>(values[0] as DependencyObject);
        var AllButtonVisibility = values[1] as AllButtonVisibility;
        foreach (DataGridColumnHeader dataGridColumnHeader in columnHeaders)
        {               
            AllButtonVisibility.AllButtonVisible = dataGridColumnHeader.Visibility == Visibility.Visible;
            if (AllButtonVisibility.AllButtonVisible)
                return Binding.DoNothing;
        }
        return Binding.DoNothing;
    }

    public List<T> GetVisualChildCollection<T>(object parent) where T : Visual
    {
        List<T> visualCollection = new List<T>();
        GetVisualChildCollection(parent as DependencyObject, visualCollection);
        return visualCollection;
    }

    private void GetVisualChildCollection<T>(DependencyObject parent, List<T> visualCollection) where T : Visual
    {
        int count = VisualTreeHelper.GetChildrenCount(parent);
        for (int i = 0; i < count; i++)
        {
            DependencyObject child = VisualTreeHelper.GetChild(parent, i);
            if (child is T)
            {
                visualCollection.Add(child as T);
            }
            else if (child != null)
            {
                GetVisualChildCollection(child, visualCollection);
            }
        }
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

原因如果不是PROGRAMMERS,那我们是什么。 :)