簡體   English   中英

WPF 將數據綁定到 RowDetailsTemplate

[英]WPF binding data to RowDetailsTemplate

我正在創建一個將顯示調查問卷的程序。 問卷按類別(Cat 1、Cat 2 等)划分。 每個類別可以包含多個問題,每個問題可以有多個選擇題答案。 我使用 DataGrid (objDatagrid) 和嵌套在 RowDetailsTemplate 中的另一個 DataGrid (objInnerDatagrid) 構建了此問卷。 我正在嘗試對其進行設置,以便在程序加載時顯示所有問題和所有答案。 這意味着默認情況下不會折疊任何內容。 我通過將外部 DataGrid 設置為:RowDetailsVisibilityMode="Visible" 來實現這一點

不幸的是,由於我的代碼,基於當前選擇的問題,每個問題的答案現在都是相同的。 當我第一次設置它時,我沒有使用 RowDetailsVisibilityMode="Visible"。 因此默認操作是折疊所有未選擇的問題。 但正如我所說,這不是我的預期設計。

我很確定我的代碼中的錯誤是在內部網格 (objInnerDataGrid) ItemsSource 綁定中。 但是不知道改成什么。


XAML:

<Grid>
    <StackPanel>
        <TextBox Controls:TextBoxHelper.Watermark="enter search term" Name="TxtFilter" Margin="10" TextChanged="TxtFilter_TextChanged" Height="25" MinWidth="250" HorizontalAlignment="Stretch"/>
        <DataGrid x:Name="objDatagrid" ItemsSource="{Binding DataView}" IsReadOnly="True" CanUserAddRows="False" CanUserDeleteRows="False" Loaded="objDatagrid_Loaded" AutoGenerateColumns="False"
              HeadersVisibility="None" ScrollViewer.VerticalScrollBarVisibility="Auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" RowDetailsVisibilityMode="Visible">
            <DataGrid.RowDetailsTemplate>
                <DataTemplate>
                    <DataGrid x:Name="objInnerDatagrid" ItemsSource="{Binding ElementName=objDatagrid, Path=SelectedItem.Answers}" CanUserAddRows="False" IsReadOnly="True" CanUserDeleteRows="False"
                              HeadersVisibility="None" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
                        <DataGrid.Columns>
                            <DataGridCheckBoxColumn ElementStyle="{DynamicResource MetroDataGridCheckBox}" 
                                                    EditingElementStyle="{DynamicResource MetroDataGridCheckBox}" 
                                                    Binding="{Binding Answers.AnswerText}"/>
                        </DataGrid.Columns>
                    </DataGrid>
                </DataTemplate>
            </DataGrid.RowDetailsTemplate>

            <DataGrid.Columns>
                <DataGridTextColumn Width="Auto" Binding="{Binding QuestionText}" IsReadOnly="True"/>
            </DataGrid.Columns>
            <DataGrid.GroupStyle>
                <GroupStyle>
                    <GroupStyle.HeaderTemplate>
                        <DataTemplate>
                            <StackPanel>
                                <TextBlock Text="{Binding Path=Name}" />
                            </StackPanel>
                        </DataTemplate>
                    </GroupStyle.HeaderTemplate>
                    <GroupStyle.ContainerStyle>
                        <Style TargetType="{x:Type GroupItem}">
                            <Setter Property="Template">
                                <Setter.Value>
                                    <ControlTemplate TargetType="{x:Type GroupItem}">
                                        <Expander Margin="15 0 15 0" Header="{Binding Path=Name}" IsExpanded="True" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
                                            <ItemsPresenter VerticalAlignment="Stretch" HorizontalAlignment="Stretch"/>
                                        </Expander>
                                    </ControlTemplate>
                                </Setter.Value>
                            </Setter>
                        </Style>
                    </GroupStyle.ContainerStyle>
                </GroupStyle>
            </DataGrid.GroupStyle>
        </DataGrid>
    </StackPanel>
</Grid>

C#:

public partial class DataEmbed : UserControl
{
    DataTable dt = new DataTable();

    public DataEmbed()
    {
        InitializeComponent();

        DataContext = this;

        _dataView = new ListCollectionView(new ObservableCollection<Question>(Populate()));
        _dataView.GroupDescriptions.Add(new PropertyGroupDescription("CategoryString"));

        CollectionView cv = (CollectionView)CollectionViewSource.GetDefaultView(DataView);
        cv.Filter = CustomFilter;
    }
    private List<Question> Populate()
    {
        return new List<Question>()
        {
            new Question()
            {
                CategoryString = "Cat 1",
                QuestionText = "Question 1",
                Answers = new ObservableCollection<Answer>
                {
                    new Answer {AnswerText = "Answer 1"},
                    new Answer {AnswerText = "Answer 2"},
                    new Answer {AnswerText = "Answer 3"},
                    new Answer {AnswerText = "Answer 4"}
                }
            },

            new Question()
            {
                CategoryString = "Cat 1",
                QuestionText = "Question 2",
                Answers = new ObservableCollection<Answer>
                {
                    new Answer {AnswerText = "Answer 5"},
                    new Answer {AnswerText = "Answer 6"},
                    new Answer {AnswerText = "Answer 7"},
                    new Answer {AnswerText = "Answer 8"},
                }
            },

            new Question()
            {
                CategoryString = "Cat 2",
                QuestionText = "Question 1",
                Answers = new ObservableCollection<Answer>
                {
                    new Answer {AnswerText = "Answer 9"},
                    new Answer {AnswerText = "Answer 10"},
                    new Answer {AnswerText = "Answer 11"},
                    new Answer {AnswerText = "Answer 12"},
                }
            }

        };
    }

    private ListCollectionView _dataView;
    public ListCollectionView DataView
    {
        get { return _dataView; }
        set { _dataView = value; }
    }

    private void objDatagrid_Loaded(object sender, RoutedEventArgs e)
    {

    }
}

課程:

public class Question
    {
        public string CategoryString { get; set; }
        public bool IsCategoryExpanded { get; set; }
        public string QuestionText { get; set; }
        public ObservableCollection<Answer> Answers { get; set; }
    }

    public class Answer
    {
        public string AnswerText { get; set; }
    }

您對內部網格綁定的假設是正確的,因為您對當前選定的行有一個顯式綁定,該實際上跳出當前項目並將其綁定到所有行

<DataGrid x:Name="objInnerDatagrid" 
           ItemsSource="{Binding ElementName=objDatagrid, Path=SelectedItem.Answers}" 

對於所有行,您想要的綁定是基於當前項的父數據上下文的相對綁定,例如

<DataGrid x:Name="objInnerDatagrid" 
           ItemsSource="{Binding Answers}" 

您可能必須明確指定DataContext ,如果是這樣,請使用:

<DataGrid x:Name="objInnerDatagrid" 
           ItemsSource="{Binding DataContext.Answers}" 

請記住,綁定最終是基於對象數據上下文的代碼反射,在大多數情況下它是從父級繼承的,因此在這些情況下,請考慮父級並相應地綁定。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM