簡體   English   中英

在XAML中設置ComboBox的DataContext

[英]Set the DataContext of a ComboBox in XAML

這是WPF MVVM應用程序的一部分。 我相信與此有關的問題是數據上下文不清楚。 該數據網格的ItemsSource是ViewModels的集合。 這是ViewModel中的一個屬性,用於顯示其余數據。 因此,所有數據都會顯示出來,甚至在SpecimentViewModel中也會顯示單個項目。 唯一不起作用的是我無法在comboBox中顯示所選的選項。 由於我一直對此感到困惑,所以我什至看不到默認的“選擇注釋”(項目0)。 正如我所說,所有其他列都會出現。 它們都是每個viewModel中的屬性。 那我的ComboBox看不到DataContext嗎?

                <DataGrid
                ItemsSource="{Binding Specimens}"
                Style="{StaticResource DataGridStyle}"
                Background="Beige"
                FontFamily="Verdana"
                FontSize="10"
                AutoGenerateColumns="False"
                HorizontalAlignment="Stretch"
                VerticalAlignment="Stretch"
                AlternatingRowBackground="Beige"
                AlternationCount="2"
                AllowDrop="False"
                CanUserAddRows="False"
                DataContext="">
                <DataGrid.Columns>
                    <DataGridTextColumn Binding="{Binding TestNumber}"
                                        Header="No."
                                        Width=".05*" />

                    <DataGridTextColumn Binding="{Binding PlyCount}"
                                        Header="Ply Count"
                                        Width=".14*" />

                    <DataGridTextColumn Binding="{Binding PlyThickness}"
                                        Header="Ply Thickness"
                                        Width=".14*" />

                    <DataGridTextColumn Binding="{Binding TearPerPly}"
                                        Width=".14*">

                        <DataGridTextColumn.Header>
                            <TextBlock Text="{Binding DataContext.SpencerDartHeading, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" />
                        </DataGridTextColumn.Header>
                    </DataGridTextColumn>

                    <DataGridTemplateColumn
                        Header="Note"
                        Width=".14*">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <ComboBox ItemsSource="{Binding ResultOptions}"
                                          SelectedItem="{Binding SelectedNote, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                                          SelectedValue="{Binding SelectedNote, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" 
                                          IsSynchronizedWithCurrentItem="True"/>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                </DataGrid.Columns>
            </DataGrid>

ViewModel看起來像這樣;

    private Specimen specimen;
    private ObservableCollection<string> resultOptions = new ObservableCollection<string>();
    public Specimen Specimen
    {
        get
        {
            return specimen;
        }
        set
        {
            specimen = value;
            RaisePropertyChanged("Specimen");
        }
    }

    public string SelectedNote
    {
        get
        {
            if (specimen.ResultNote == null)
                specimen.ResultNote = "Select Note";
            return specimen.ResultNote;
        }
        set
        {
            specimen.ResultNote = value;
            RaisePropertyChanged();
        }
    }

    public ObservableCollection<string> ResultOptions
    {
        get { return resultOptions; }
        set
        {
            resultOptions = value;
            RaisePropertyChanged();
        }
    }

標本模型僅具有一些測試屬性和ResultNote字符串屬性。 因此,TestViewModel具有單個測試的屬性,其中之一是稱為Specimens的SpecimenViewModels的集合。 每個SpecimenViewModels都有一個屬性,它是ResultNote。 該結果注釋是從組合框中選擇的,該組合框中裝有SpeciimenViewModel中稱為ResultOptions的選項的集合。 所選值將放入屬性“ ResultNote”。

嘗試這個:

<DataGridTemplateColumn Header="Note"
                        Width=".14*" 
                        SortMemberPath="SelectedNote">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <ComboBox ItemsSource="{Binding ResultOptions}"
                      SelectedItem="{Binding SelectedNote, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                      SelectedValuePath="SelectedNote" />
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

在標頭綁定中,嘗試使用SelectedItem屬性而不是DataContext

<TextBlock Text="{Binding SelectedItem.SpencerDartHeading, ..." />

這是視圖:

    <Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <DataGrid
                ItemsSource="{Binding Specimens}"

                Background="Beige"
                FontFamily="Verdana"
                FontSize="10"
                AutoGenerateColumns="False"
                HorizontalAlignment="Stretch"
                VerticalAlignment="Stretch"
                AlternatingRowBackground="Beige"
                AlternationCount="2"
                AllowDrop="False"
                CanUserAddRows="False"
                >
            <DataGrid.Columns>
                <DataGridTextColumn Binding="{Binding TestNumber}"
                                        Header="No."
                                        Width=".05*" />

                <DataGridTextColumn Binding="{Binding PlyCount}"
                                        Header="Ply Count"
                                        Width=".14*" />

                <DataGridTextColumn Binding="{Binding PlyThickness}"
                                        Header="Ply Thickness"
                                        Width=".14*" />

                <DataGridTextColumn Binding="{Binding TearPerPly}"
                                        Width=".14*">

                    <DataGridTextColumn.Header>
                        <TextBlock Text="{Binding DataContext.SpencerDartHeading, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" />
                    </DataGridTextColumn.Header>
                </DataGridTextColumn>

                <DataGridTemplateColumn Header="Note"
                        Width=".14*" 
                        SortMemberPath="SelectedNote">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <ComboBox ItemsSource="{Binding ResultOptions}"
                      SelectedItem="{Binding SelectedNote, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                      SelectedValuePath="SelectedNote" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

和ViewModel:

public class SpecimenViewModel
    {
        private Specimen specimen;
        private ObservableCollection<string> resultOptions = new ObservableCollection<string>();

        public SpecimenViewModel(Specimen specimen)
        {           
            resultOptions.Add("Select Note");
            resultOptions.Add("Select 1");
            resultOptions.Add("Select 2");
            resultOptions.Add("Select 3");

            this.specimen = specimen;
            RaisePropertyChanged("SelectedNote");
        }


        public Specimen Specimen
        {
            get
            {
                return specimen;
            }
            set
            {
                specimen = value;
                RaisePropertyChanged("Specimen");
            }
        }

        public string SelectedNote
        {
            get
            {
                if (specimen.ResultNote == null)
                    specimen.ResultNote = "Select Note";
                return specimen.ResultNote;
            }
            set
            {
                specimen.ResultNote = value;
                RaisePropertyChanged();
            }
        }

        public ObservableCollection<string> ResultOptions
        {
            get { return resultOptions; }
            set
            {
                resultOptions = value;
                RaisePropertyChanged();
            }
        }


        }

我感謝大家的回答。 特別是Kasper和Ncfuncion。 他們為答案做了很多工作。 不幸的是,他們都沒有為我工作。 事實證明,我的XAML代碼很好。 我終於發現問題出在數據匯編中。 我無法解釋為什么會出現問題。 我可以追溯到我知道它可以正常工作的時間(很幸運,我使用了GIT版本控制)。 我一遍又一遍地檢查代碼,最后發現我在修改過程中更改了一行。 我確定已經調試並看到了正確的值,但是它們並沒有出現在數據網格中。 哦,好吧,我的腦子回了。 對於想要查看此處工作代碼外觀的任何人,都是XAML。 為了簡潔起見,我跳過了其他專欄。

                <DataGrid
                ItemsSource="{Binding Specimens}"
                Style="{StaticResource DataGridStyle}"
                Background="Beige"
                FontFamily="Verdana"
                FontSize="10"
                AutoGenerateColumns="False"
                HorizontalAlignment="Stretch"
                VerticalAlignment="Stretch"
                AlternatingRowBackground="Beige"
                AlternationCount="2"
                AllowDrop="False"
                CanUserAddRows="False"
                >
                <DataGrid.Columns> 
                   <DataGridTemplateColumn
                        Header="Note"
                        Width=".14*">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <ComboBox ItemsSource="{Binding ResultOptions}"
                                          SelectedItem="{Binding SelectedNote, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                                          SelectedValue="{Binding SelectedNote}"/>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                </DataGrid.Columns>
            </DataGrid>

就像為DataGrid中的最后一個文本列設置的內容一樣,通過指定RelativeSource屬性來使用數據綁定,也可以使用這種方法為ComboBox設置ItemsSource ,如下所示:

                <DataGridTemplateColumn
                    Header="Note"
                    Width=".14*">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <ComboBox ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}, Path=DataContext.ResultOptions}"
                                      SelectedItem="{Binding SelectedNote, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                                      IsSynchronizedWithCurrentItem="True"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>

至於SelectedValueSelectedItem ,我認為您應該只設置其中之一。

暫無
暫無

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

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