基于 ComboBox 选择,使用 DataGrid CellTemplate 中的 DataTrigger 将另一个 ComboBox 更改为 TextBox

问题描述 投票:0回答:1

我有一个 DataGrid,我在其中使用 CellTemplate 来定义各种数据列。 像下面

<DataGridTemplateColumn Header="Movie Source" Width="*">
      <DataGridTemplateColumn.CellTemplate>
           <DataTemplate>
              <ComboBox x:Name="cbMovieSource" Width="100" 
                      ItemsSource="{Binding Path=MovieSources, Mode=Twoway}" 
                      SelectedItem="{Binding Path=MovieSourceSelected, Mode=Twoway, UpdateSourceTrigger=PropertyChanged}" 
                      IsSynchronizedWithCurrentItem="False">
              </ComboBox>
           </DataTemplate>
       </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>

现在,我在该 DataGrid 中有 3/4 数据列,基于一个数据列“Movie Source”- ComboBox 的值 “Manual Entry”,我必须将另一个数据列'Movie Hall'ComboBox更改为TextBox以允许用户输入数据。我已经使用数据触发器来做到这一点。

问题是--

  1. 虽然最初加载页面时它显示空白而不是默认的 ComboBox -'Movie Hall'。

  2. 当我将Movie Source ComboBox 的值更改为 “手动输入”不会将 Movie Hall ComboBox 更改为 TextBox 但如果我单击 那个空白的文本框出现了。

我正在使用 Observable Collection 作为 Item 源,数据加载不是问题。 但是我将如何最初获得 ComboBox 但从 ComboBox 中选择特定值后,进入 TextBox 是这里的问题。

我的数据触发代码如下 -

<DataGridTemplateColumn Header="Movie Hall" Width="*">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <ContentControl>
                <ContentControl.Style>
                    <Style TargetType="av:ContentControl" >
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding ElementName=cbMovieSource, Path=SelectedItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
                                <Setter Property="ContentTemplate">
                                    <Setter.Value>
                                        <DataTemplate>
                                            <ComboBox x:Name="cbMovieHall" Width="120" 
                                                      ItemsSource="{Binding MovieHalls, Mode=Twoway}" 
                                                      SelectedItem="{Binding MovieHallsSelected, Mode=Twoway, UpdateSourceTrigger=PropertyChanged}">      
                                            </ComboBox>
                                        </DataTemplate>
                                    </Setter.Value>
                                </Setter>
                            </DataTrigger>
                            <DataTrigger Binding="{Binding Path=MovieSourceSelected}" Value ="Manual Entry">
                                <Setter Property="ContentTemplate">
                                    <Setter.Value>
                                        <DataTemplate>
                                            <TextBox Width="120"  Visibility="Visible" 
                                                Text="{Binding DataContext.TextA, RelativeSource={RelativeSource AncestorType=DataGridRow}}"/>
                                        </DataTemplate>
                                    </Setter.Value>
                                </Setter>
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </ContentControl.Style>
            </ContentControl>
       </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

初始加载

选择值后

点击Movie Hall标题下的空白区域后-

wpf xaml triggers datagrid datatrigger
1个回答
0
投票

我觉得你只需要一个DataTrigger,第二个。在 Style 中单独使用第一个 DataTrigger 中的 Setter(这将是默认设置),然后让 Style.Triggers 部分仅包含第二个 DataTrigger:

<DataGridTemplateColumn.CellTemplate>
    <DataTemplate>
        <ContentControl>
            <ContentControl.Style>
                <Style TargetType="av:ContentControl">
                    <Setter Property="ContentTemplate">
                        <Setter.Value>
                            <DataTemplate>
                                <ComboBox x:Name="cbMovieHall"
                                            Width="120"
                                            ItemsSource="{Binding MovieHalls, Mode=Twoway}"
                                            SelectedItem="{Binding MovieHallsSelected, Mode=Twoway, UpdateSourceTrigger=PropertyChanged}">
                                </ComboBox>
                            </DataTemplate>
                        </Setter.Value>
                    </Setter>
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding Path=MovieSourceSelected}"
                                        Value="Manual Entry">
                            <Setter Property="ContentTemplate">
                                <Setter.Value>
                                    <DataTemplate>
                                        <TextBox Width="120"
                                                    Visibility="Visible"
                                                    Text="{Binding DataContext.TextA, RelativeSource={RelativeSource AncestorType=DataGridRow}}" />
                                    </DataTemplate>
                                </Setter.Value>
                            </Setter>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </ContentControl.Style>
        </ContentControl>
    </DataTemplate>
</DataGridTemplateColumn.CellTemplate>

Style 中的第一个 Setter 将默认应用。然后,如果满足 DataTrigger 条件,该 DataTrigger 中的 Setter 也将被应用,覆盖第一个 Setter,在这种情况下,将 ContentTemplate 设置为带有 TextBox 的 DataTemplate。

您还可以通过让 ComboBox 和 TextBox 基于 DataTrigger 隐藏自己而不是使用 ContentControl 来简化事情:

<DataGridTemplateColumn Header="Movie Hall"
                        Width="*">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <Grid>
                <ComboBox x:Name="cbMovieHall"
                            Width="120"
                            ItemsSource="{Binding MovieHalls, Mode=Twoway}"
                            SelectedItem="{Binding MovieHallsSelected, Mode=Twoway, UpdateSourceTrigger=PropertyChanged}">
                    <ComboBox.Style>
                        <Style TargetType="ComboBox">
                            <Setter Property="Visibility"
                                    Value="Visible" />
                            <Style.Triggers>
                                <DataTrigger Binding="{Binding Path=MovieSourceSelected}"
                                                Value="Manual Entry">
                                    <Setter Property="Visibility"
                                            Value="Hidden" />
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </ComboBox.Style>
                </ComboBox>
                <TextBox Width="120"
                            Visibility="Visible"
                            Text="{Binding DataContext.TextA, RelativeSource={RelativeSource AncestorType=DataGridRow}}">
                    <TextBox.Style>
                        <Style TargetType="TextBox">
                            <Setter Property="Visibility"
                                    Value="Hidden" />
                            <Style.Triggers>
                                <DataTrigger Binding="{Binding Path=MovieSourceSelected}"
                                                Value="Manual Entry">
                                    <Setter Property="Visibility"
                                            Value="Visible" />
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </TextBox.Style>
                </TextBox>
            </Grid>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

您不必为您的 ComboBoxes(

cboMovieSource
cbMovieHall
)命名,因为它们正在使用绑定。如果您需要在代码隐藏中访问它们,您会为它们命名,但从您的 XAML 来看,您似乎不需要这样做。

© www.soinside.com 2019 - 2024. All rights reserved.