我有一个 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以允许用户输入数据。我已经使用数据触发器来做到这一点。
问题是--
虽然最初加载页面时它显示空白而不是默认的 ComboBox -'Movie Hall'。
当我将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标题下的空白区域后-
我觉得你只需要一个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 来看,您似乎不需要这样做。