我有一个Datagrid,其中一列是Combobox。问题是:如果Combobox在Datagrid之外,SelectedItem将运行良好,但如果相同的组合代码在网格内部,则不会工作。这是代码。
<StackPanel x:Name="stackPanel" Grid.Row="2" Background="White" Width="{Binding Width, ElementName=lvwPPVEvents}" Margin="0,0,0,1.875" >
<ComboBox ItemsSource="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type UserControl}}, Path=DataContext.TestNumberofInstallments}"
SelectedItem="{Binding Path=DataContext.TestInstall, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}},UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"/>
<DataGrid ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Auto"
ItemsSource="{Binding FilteredOrderedEvents,UpdateSourceTrigger=PropertyChanged,NotifyOnSourceUpdated=True}"
SelectedItem="{Binding EventSelected}" CanUserReorderColumns="False" CanUserAddRows="False" CanUserDeleteRows="False"
CellStyle="{StaticResource ClearlstItmContainerStyle}" AlternatingRowBackground="LightGray" MaxHeight="125"
AlternationCount="2" SelectionMode="Single" Background="White" AutoGenerateColumns="False" Margin="0,2"
HorizontalGridLinesBrush="White" Width="{Binding ActualWidth, ElementName=stackPanel}" HorizontalAlignment="Left" HorizontalContentAlignment="Stretch">
<DataGrid.Columns>
<DataGridTextColumn Width="50" Header="Status" Binding="{Binding Path= Status}" IsReadOnly="True" />
<DataGridTextColumn Width="60" Header="Order ID" Binding="{Binding Path= EventID}" IsReadOnly="True"/>
<DataGridTextColumn Width="140" Header="Title" Binding="{Binding Path= Desc}" IsReadOnly="True"/>
<DataGridTextColumn Width="120" Header="Date / Time" Binding="{Binding Path= StartDate}" IsReadOnly="True"/>
<DataGridTextColumn Width="60" Header="Channel" Binding="{Binding Path= Channels}" IsReadOnly="True"/>
<DataGridTextColumn Width="50" Header="Cost" Binding="{Binding Path= Cost,StringFormat=N2}" IsReadOnly="True"/>
<!--<DataGridComboBoxColumn Header="Install" Width="Auto" ItemsSource="{Binding colNumberofInstallments}"/>-->
<DataGridTemplateColumn Header="Install">
<!--<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<wpf:IntegerUpDown Value="{Binding NumberOfInstallments}" FormatString="N0" Increment="1" Maximum="{Binding Max}" Minimum="1"/>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>-->
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<!--<TextBlock Text="{Binding NumberOfInstallments}"/>-->
<ComboBox ItemsSource="{Binding Path=DataContext.TestNumberofInstallments,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type UserControl}}}"
SelectedItem="{Binding Path=DataContext.TestInstall, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}},UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Width="37" Header="Max" Binding="{Binding Path= Max}" IsReadOnly="True"/>
</DataGrid.Columns >
</DataGrid>
</StackPanel>
答案 0 :(得分:0)
它不起作用,主要是因为DataGridTemplateColumn不是可视树的一部分。因此,RelativeSource并不意味着该上下文中的任何内容。
你可以做一些简单的hackery:
<DataGrid.Resources>
<TextBlock x:Key="TempHack" DataContext="{YOUR ACTUAL BINDING HERE}"/>
</DataGrid.Resources>
然后你可以像这样引用它:
<DataGridTemplateColumn Header="{Binding Source={StaticResource TempHack}}" />
答案 1 :(得分:0)
有许多不同的控件可以被视为UserControl
,因此我怀疑您没有使用UserControl
绑定获得正确的RelativeSource
我建议您使用UserControl的完整类名而不是仅仅尝试在VisualTree中找到最接近的UserControl
<ComboBox
ItemsSource="{Binding DataContext.TestNumberofInstallments,
RelativeSource={RelativeSource AncestorType={x:Type local:MyUserControl}}}"
SelectedItem="{Binding DataContext.TestInstall,
RelativeSource={RelativeSource AncestorType={x:Type local:MyUserControl}}}" />
我做了一个快速测试,似乎工作得很好,但令我惊讶的是我无法在绑定中使用ElementName
。可能ChrisDD is correct关于ElementName
无法使用DataGridTemplateColumn
,因为与VisualTree
有关,但您绝对可以在RelativeSource
中使用DataGridTemplateColumn
{1}}
<StackPanel x:Name="RootPanel">
<ComboBox ItemsSource="{Binding ElementName=RootPanel, Path=DataContext.Test}"
SelectedItem="{Binding ElementName=RootPanel, Path=DataContext.SelectedTest}"
DisplayMemberPath="TestValue"/>
<DataGrid ItemsSource="{Binding Test}">
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type StackPanel}}, Path=DataContext.Test}"
SelectedItem="{Binding RelativeSource={RelativeSource AncestorType={x:Type StackPanel}}, Path=DataContext.SelectedTest}"
DisplayMemberPath="TestValue"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</StackPanel>
你应该注意的一件事是WPF通过引用而不是值来比较对象,因此SelectedItem
必须指向内存中与ItemsSource
中的项完全相同的引用,或者它不会被视为匹配并被选中。
例如,
ItemsSourceProperty = new ObservableCollection<SomeObject>()
{
new SomeObject(1),
new SomeObject(2),
new SomeObject(3)
};
SelectedItemProperty = ItemsSourceProperty.FirstOrDefault(); // Works
SelectedItemProperty = new SomeObject(1); // Won't work