wpf 根据组合框选择,使用DataGrid CellTemplate中的DataTrigger将另一个组合框更改为TextBox

ep6jt1vc  于 2023-05-19  发布在  其他
关注(0)|答案(1)|浏览(198)

我有一个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>

现在,我有3/4的数据列在该DataGrid中,基于一个数据列'Movie Source'-ComboBox的值“Manual Entry",我必须将另一个数据列'Movie Hall' ComboBox更改为TextBox以允许用户输入数据。我使用数据触发器来实现这一点。
问题是
1.加载页面时,最初显示空白,而不是默认的组合框-“电影厅”。
1.当我将Movie SourceComboBox的值更改为“Manual Entry”时,它不会将Movie HallComboBox更改为TextBox,但如果我单击出现的空白区域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>

初始装载

选择值


点击电影厅标题下的空白区域后-

nhhxz33t

nhhxz33t1#

我认为你只需要一个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>

默认情况下,将应用样式中的第一个Setter。然后,如果满足DataTrigger条件,则该DataTrigger中的Setter也将被应用,覆盖第一个Setter,并且在这种情况下,将ContentTemplate设置为其中具有TextBox的DataTemplate。
您还可以通过让ComboBox和TextBox基于DataTrigger而不是使用ContentControl来处理隐藏自己来简化事情:

<DataGridTemplateColumn Header="Movie Hall"
                        Width="*">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <Grid>
                <ComboBox 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>

此XAML有一个ComboBox,默认情况下它是可见的,当MovieSourceSelectedManual Entry时它被设置为隐藏。默认情况下,TextBox是隐藏的,并使用Manual Entry设置为可见。
关于用于Movie Source ComboBox的Binding,如果您使用String作为Dependency Property,请确保它使用SelectedValueSelectedValuePath

<ComboBox SelectedValue="{Binding MovieSourceSelected, Mode=TwoWay}" SelectedValuePath="Content">
    <ComboBoxItem Content="Some option" />
    <ComboBoxItem Content="Manual Insertion" />
    <ComboBoxItem Content="Some other option" />
</ComboBox>

顺便说一下,您不应该命名您的ComboBox(cboMovieSourcecbMovieHall),因为它们使用绑定。如果您需要在代码隐藏中访问它们,您可以命名它们,但从XAML来看,您似乎不需要这样做。

相关问题