1

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

2 回答 2

0

它不起作用,主要是因为 DataGridTemplateColumn 不是可视化树的一部分。因此,RelativeSource 在这种情况下并没有真正的意义。

但是,您可以做简单的骇客:

    <DataGrid.Resources>
    <TextBlock x:Key="TempHack" DataContext="{YOUR ACTUAL BINDING HERE}"/>
   </DataGrid.Resources>

然后你可以像这样引用它:

 <DataGridTemplateColumn Header="{Binding Source={StaticResource TempHack}}" />
于 2012-08-21T17:48:41.983 回答
0

有许多不同的控件可以被认为是 a ,所以我怀疑你的绑定UserControl没有正确UserControlRelativeSource

我建议使用您的 UserControl 的完整类名,而不是仅仅尝试UserControl在 VisualTree中找到最接近的

<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关于不能在 a 中使用是ElementName正确的,因为DataGridTemplateColumn它与VisualTreeRelativeSourceDataGridTemplateColumn

<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
于 2012-08-21T19:21:38.240 回答