【问题标题】:WPF - Setting DataContext for a Trigger's setterWPF - 为触发器的设置器设置 DataContext
【发布时间】:2009-12-29 20:08:07
【问题描述】:

我最近重构了一个DataTrigger。它曾经将DataContext 设置为ListBoxItem。现在是ContentPresenter

代码如下:

<DataTemplate.Triggers>
    <DataTrigger Value="True">
        <DataTrigger.Binding>
            <MultiBinding Converter="{StaticResource DisableWorkItemConverter}">
                <Binding ElementName="MainForm" Path="PickedWorkItemID"/>
                <Binding Path="WorkItemForColumn.Id"/>
            </MultiBinding>
        </DataTrigger.Binding>
        <Setter Property="IsEnabled" Value="False"/>
        <Setter Property="loc:Main.IsCurrentItemEnabledChanged" Value="True"/>
    </DataTrigger>
</DataTemplate.Triggers>

IsCurrentItemEnabledChangedOnChange 中,我可以看到我可以使用以下代码(在后面的代码中)到达ListBoxItem

listBoxItem = (ListBoxItem)Main.Instance.lstQueryResults.ItemContainerGenerator.
               ContainerFromItem(((ContentPresenter)d).Content);

但是,我无法看到设置DataContext 以便我的SetterIsEnabled 将设置ListBoxItem 的启用状态而不是ContentPresenter

(我会在IsCurrentItemEnabledChangedOnChange 中执行此操作,但是该属性已经有点小技巧了,当触发器设置为 false 时它不会重新启用该项目。)

有什么想法吗?


有人建议我提供更多来提供上下文:

这是我的模板 XAML。

<DataTemplate x:Key="ColumnTemplate">
    <Border Name="ItemBorder" BorderBrush="Black" BorderThickness="1" CornerRadius="2" Padding="2">
        <WrapPanel>                   
            <TextBlock Margin="0,0,5,0">
                <TextBlock.Text>
                    <Binding Path="Name" Converter="{StaticResource GetVisibilityOfColumnTitles}"/>
                </TextBlock.Text>
            </TextBlock>
            <TextBlock Text="{Binding Value}" Margin="0,0,10,0" FontWeight="Bold" />
        </WrapPanel>
    </Border>
</DataTemplate>

<DataTemplate x:Key="RowTemplate">
    <Border x:Name="ItemBorder" BorderThickness="1" BorderBrush="#D4D4FF">
        <Grid x:Name="ItemGrid" Width="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsPresenter}}, Path=ActualWidth}" ScrollViewer.CanContentScroll="True" Margin="2">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="20" />
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="30" />
            </Grid.ColumnDefinitions>
            <Grid.Background>
                <Binding Path="WorkItemForColumn.Type" Converter="{StaticResource WorkItemTypeToColorConverter}" />
            </Grid.Background>

            <CheckBox VerticalAlignment="Center" Grid.Column="0" IsChecked="{Binding
                                      RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}},
                                      Mode=TwoWay, Path=IsSelected}" Name="chkIsSelected" />

            <ItemsControl Grid.Column="1" Margin="5,0,5,0" ItemsSource="{Binding}" ItemTemplate="{StaticResource ColumnTemplate}" >
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <WrapPanel Orientation="Horizontal"></WrapPanel>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
            </ItemsControl>


            <Button HorizontalAlignment="Right" x:Name="btnPick" Grid.Column="3" Style="{StaticResource roundButton}" Width="15" Height="15" Tag="{Binding WorkItemForColumn.Id}" Margin="5,0,10,0">
                <Path Fill="DarkBlue">
                    <Path.Data>
                        <PathGeometry>
                            <PathFigure StartPoint="2,0" IsClosed="True">
                                <LineSegment Point="7,5"/>
                                <LineSegment Point="2,10"/>
                            </PathFigure>
                            <PathFigure StartPoint="2,2" IsClosed="True">
                                <LineSegment Point="5,5"/>
                                <LineSegment Point="2,8"/>
                            </PathFigure>
                        </PathGeometry>
                    </Path.Data>
                </Path>
            </Button>
        </Grid>
    </Border>
    <DataTemplate.Triggers>
        <DataTrigger Value="True">
            <DataTrigger.Binding>
                <MultiBinding Converter="{StaticResource DisableWorkItemConverter}">
                    <Binding ElementName="MainForm" Path="PickedWorkItemID"/>
                    <Binding Path="WorkItemForColumn.Id"/>
                </MultiBinding>
            </DataTrigger.Binding>
            <Setter Property="IsEnabled" Value="False"/>
            <Setter Property="loc:Main.IsCurrentItemEnabledChanged" Value="True"/>
        </DataTrigger>
    </DataTemplate.Triggers>
</DataTemplate>

这是列表框的 XAML:

<ListBox ScrollViewer.HorizontalScrollBarVisibility="Disabled" Button.Click="PickWorkItem_Click" SelectionMode="Multiple" ItemTemplate="{StaticResource RowTemplate}"  Name="lstQueryResults" SelectionChanged="lstQueryResults_SelectionChanged" >
    <ListBox.Resources>
        <Style TargetType="{x:Type ListBoxItem}">
            <Style.Resources>
                <SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="Black"/>
                <SolidColorBrush x:Key="{x:Static SystemColors.ControlTextBrushKey}" Color="Black"/>
            </Style.Resources>
        </Style>
    </ListBox.Resources>
</ListBox>

DataContext 在代码中设置如下:

private void ChangeQueryResultListSource(WorkItemCollection queryResults, bool b)
{
    // Un-hook the selection event while we change the ItemsSource
    Form.ToggleOnSelectEvent(false);

    // This sets the DataContext
    QueryDisplay = GetDisplayValues(queryResults);

    Form.QueryResultListSource = QueryDisplay;
    // Rewire the selection events back in
    Form.ToggleOnSelectEvent(true);


    foreach (WorkItem item in Pad.Keys)
    {
        Form.SelectQueryResultItem(item);
    }
}

private List<List<WorkItemColumn>> GetDisplayValues(WorkItemCollection queryResults)
{
    var result = new List<List<WorkItemColumn>>();
    foreach (WorkItem workItem in queryResults)
    {
        var row = GetQueryColumns(queryResults.DisplayFields, workItem);
        result.Add(row);
    }
    return result;
}

private List<WorkItemColumn> GetQueryColumns(DisplayFieldList fields, WorkItem workItem)
{
    var row = new List<WorkItemColumn>();
    foreach (FieldDefinition column in fields)
    {
        var workItemColumn = new WorkItemColumn { Name = column.Name, Value = workItem[column.Name], WorkItemForColumn = workItem };
        row.Add(workItemColumn);
    }

    return row;
}

WorkItemColumn 是一个具有名称-值对和对数据的引用(WorkItem 对象)的类。

【问题讨论】:

  • 我可能是唯一一个,但我对你的问题有点困惑。 “但是,我无法看到设置 DataContext 以便我的 Setter for IsEnabled 将设置 ListBoxItem 而不是 ContentPresenter 的启用状态。”

标签: wpf data-binding binding datacontext datatrigger


【解决方案1】:

很抱歉简短的回答,但您应该将IsEnabled 的触发器和设置器逻辑移回ListBoxItem 样式:

<Style TargetType="{x:Type ListBoxItem}">
    <Style.Resources>
        <SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="Black"/>
        <SolidColorBrush x:Key="{x:Static SystemColors.ControlTextBrushKey}" Color="Black"/>
    </Style.Resources>
    <Style.Triggers>
        <DataTrigger Value="True">
            <DataTrigger.Binding>
                <MultiBinding Converter="{StaticResource DisableWorkItemConverter}">
                    <Binding ElementName="MainForm" Path="PickedWorkItemID"/>
                    <Binding Path="WorkItemForColumn.Id"/>
                </MultiBinding>
            </DataTrigger.Binding>
            <Setter Property="IsEnabled" Value="False"/>
        </DataTrigger>
    </Style.Triggers>
</Style>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-09
    • 2016-05-02
    • 2016-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-14
    相关资源
    最近更新 更多