【问题标题】:Contract expander on losing focus失去焦点的合同扩展器
【发布时间】:2018-07-05 17:10:37
【问题描述】:

每当单元格获得焦点时,我都需要扩展器来扩展。

除此之外,我希望每当单元格失去焦点时扩展器就会收缩。

<DataGridTemplateColumn.CellTemplate>
    <DataTemplate>
        <Expander VerticalAlignment="Stretch"    
                  IsExpanded="{Binding Path=IsFocused,
                                       Mode=OneWay,
                                       RelativeSource={RelativeSource 
                                            Mode=FindAncestor, 
                                            AncestorType=DataGridCell},
                  UpdateSourceTrigger=LostFocus}">
        <!--Expander.Content-->
        </Expander>
    </DataTemplate>
</DataGirdTemplateColumn.CellTemplate>

这个解决方案只是扩展而不是收缩。

我哪里错了?

注意事项:

DataGrid.SelectionMode="Single"
DataGrid.SelectionUnit="Cell"

【问题讨论】:

  • 你在哪里点击获取LostFocus,你点击另一个单元格吗?
  • 是的,就是这样
  • @Milan 可能是 .. 问题是,IsFocused 是只读的,所以我不能使用除 OneWay 之外的任何东西
  • 我编辑的代码对您来说是否可行? IsFocused 是只读的,是的,但是即使您也使用 setter 绑定到属性,问题仍然存在。单向绑定会导致这种情况,但您不能在上面的 sn-p 中使用双向绑定
  • @Milan 它似乎有效。由于某种原因,它只在第一个列上工作,但我想我这边有一个错误../

标签: wpf xaml datagrid styles expander


【解决方案1】:

“这个解决方案只是扩张而不是收缩。”

单击你的扩展器将其展开一次,然后尝试单击datagridcell中的其他位置,它将不起作用,第一次手动扩展时绑定被破坏,并且当datagridcell IsFocused为true时扩展器不会自动扩展了。如果您在 viewmodel 中的简单 bool 属性上使用单向绑定,也会发生同样的情况。

编辑:

尝试使用这个扩展器,我相信它可以满足您的需求:

.xaml

<local:MyExpander DataGridCellToObserve="{Binding RelativeSource={RelativeSource AncestorType=DataGridCell}}" >

.cs

public class MyExpander : Expander
{
    public MyExpander()
    {
        this.IsEnabled = false;
    }

    public DataGridCell DataGridCellToObserve
    {
        get { return (DataGridCell)GetValue(DataGridCellToObserveProperty); }    
        set { SetValue(DataGridCellToObserveProperty, value); }
    }

    public static readonly DependencyProperty DataGridCellToObserveProperty =
        DependencyProperty.Register("DataGridCellToObserve", typeof(DataGridCell), typeof(MyExpander), new PropertyMetadata(test));

    private static void test(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        (e.NewValue as DataGridCell).Selected += (d as MyExpander).setExpanded;
        (e.NewValue as DataGridCell).Unselected += (d as MyExpander).setExpandedFalse;
    }

    private void setExpanded(object sender, RoutedEventArgs e)
    {
        this.SetValue(IsExpandedProperty, true);
        this.IsEnabled = true;
    }

    void setExpandedFalse(object sender, RoutedEventArgs e)
    {
        this.SetValue(IsExpandedProperty, false);
        this.IsEnabled = false;
    }
}

【讨论】:

  • 您的解决方案不干净。每次属性更改时,您都将添加事件处理程序,最后它会减慢控件的速度。应该有更多的逻辑来添加一次事件处理程序。
  • 但只有在 MyExpander 在 xaml 中实例化后才设置该属性,对吗?无论如何,我确信 OP 能够根据需要进行清理。也欢迎编辑;b
【解决方案2】:

这是一个依赖较少的解决方案(如果您还没有使用混合行为):

<Expander Header="Hello" Content="Goodbye">
    <Expander.Style>
        <Style TargetType="Expander">
            <Style.Triggers>
                <EventTrigger RoutedEvent="LostFocus">
                    <EventTrigger.Actions>
                        <BeginStoryboard>
                            <BeginStoryboard.Storyboard>
                                <Storyboard TargetProperty="IsExpanded">
                                    <BooleanAnimationUsingKeyFrames>
                                        <DiscreteBooleanKeyFrame Value="False" KeyTime="0" />
                                    </BooleanAnimationUsingKeyFrames>
                                </Storyboard>
                            </BeginStoryboard.Storyboard>
                        </BeginStoryboard>
                    </EventTrigger.Actions>
                </EventTrigger>
                <EventTrigger RoutedEvent="GotFocus">
                    <EventTrigger.Actions>
                        <BeginStoryboard>
                            <BeginStoryboard.Storyboard>
                                <Storyboard TargetProperty="IsExpanded">
                                    <BooleanAnimationUsingKeyFrames>
                                        <DiscreteBooleanKeyFrame Value="True" KeyTime="0" />
                                    </BooleanAnimationUsingKeyFrames>
                                </Storyboard>
                            </BeginStoryboard.Storyboard>
                        </BeginStoryboard>
                    </EventTrigger.Actions>
                </EventTrigger>
            </Style.Triggers>
        </Style>
    </Expander.Style>
</Expander>

【讨论】:

  • 手动单击扩展器不会将其关闭。另外,选择一个单元格并不意味着扩展器获得焦点,所以当用户选择一个单元格时它不会自动展开
猜你喜欢
  • 1970-01-01
  • 2010-11-16
  • 2020-05-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多