簡體   English   中英

在DataGrid內綁定多列組合框的選定值

[英]Bind selected value of a multicolumn combobox inside DataGrid

工作示例:

我有一個稱為組的表,如下所示:

在此處輸入圖片說明

看完上面的圖像后,我想您可能已經知道主鍵和外鍵存在於同一張表中。 我認為這就是開發人員所謂的循環引用。

在MainWindow.xaml中,我有一個DataGrid,其中包含三列,即組名稱,父名稱,描述。 xaml看起來像:

<Window .......>

    <Window.DataContext>
        <self:MainWindowViewModel />
    </Window.DataContext>

    <DataGrid ItemsSource="{Binding Groups}" TabIndex="1">

        <DataGrid.Columns>

            <DataGridTemplateColumn Header="Group Name" Width="2*">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding GroupName}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
                <DataGridTemplateColumn.CellEditingTemplate>
                    <DataTemplate>
                        <TextBox Text="{Binding GroupName}" />
                    </DataTemplate>
                </DataGridTemplateColumn.CellEditingTemplate>
            </DataGridTemplateColumn>

            <DataGridTemplateColumn Header="Parent" Width="2*">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding ParentID, Converter={StaticResource GroupIDToGroupNameConverter}}" />
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
                <DataGridTemplateColumn.CellEditingTemplate>
                    <DataTemplate>
                        <ComboBox ItemsSource="{Binding DataContext.GroupsCollection, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}"
                                  SelectedValue="{Binding ParentID}"
                                  SelectedValuePath="GroupID"
                                  DisplayMemberPath="GroupName"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellEditingTemplate>
            </DataGridTemplateColumn>

            <DataGridTemplateColumn Header="Description" Width="2*">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Description}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
                <DataGridTemplateColumn.CellEditingTemplate>
                    <DataTemplate>
                        <TextBox Text="{Binding Description}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellEditingTemplate>
            </DataGridTemplateColumn>

        </power:PowerDataGrid.Columns>

    </power:PowerDataGrid>

</Window>

現在我有一個名為MainWindowViewModel的ViewModel

public class MainWindowViewModel : INotifyPropertyChanged
{
    public MainWindowViewModel()
    {
        SampleDBContext sampleDBContext = new SampleDBContext();
        Groups = new ObservableCollection<Group>();
        GroupsCollection = new ObservableCollection<Group>(from g in sampleDBContext.Groups select g);
    }

    private ObservableCollection<Group> _groups;
    public ObservableCollection<Group> Groups
    {
        get
        {
            return _groups;
        }
        set
        {
            _groups = value;
            OnPropertyChanged("Groups");
        }
    }

    private ObservableCollection<Group> _groupsCollection;
    public ObservableCollection<Group> GroupsCollection
    {
        get
        {
            return _groupsCollection;
        }
        set
        {
            _groupsCollection = value;
            OnPropertyChanged("GroupsCollection");
        }
    }

    #region INotifyPropertyChanged

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propertryName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertryName));
        }
    }

    #endregion
}

GroupIDToGroupName.cs //轉換器

public class GroupIDToGroupName : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value != null)
        {
            SampleDBContext sampleDBContext = new SampleDBContext();
            return (from g in sampleDBContext.Groups
                    where g.GroupID == (int)value
                    select g.GroupName).FirstOrDefault();
        }
        else
        {
            return "";
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        SampleDBContext sampleDBContext = new SampleDBContext();
        return (from g in sampleDBContext.Groups
                where g.GroupName == (string)value
                select g.GroupID).FirstOrDefault();
    }
}

在App.xaml中:

<self:GroupIDToGroupName x:Key="GroupIDToGroupNameConveerter" />

我的案例(與上述示例非常相似):

我只想在DataGrid中使用多列組合框而不是簡單的組合框。

我有兩個表:

在此處輸入圖片說明

現在,我已經完全按照上述代碼設置了代碼。

我添加了一個名為GroupIDAndNameWithCorrespondingEffect的額外類,例如:

public class GroupIDAndNameWithCorrespondingEffect : INotifyPropertyChanged
{
    private int _groupID;
    public int GroupID
    {
        get
        {
            return _groupID;
        }

        set
        {
            _groupID = value;
            OnPropertyChanged("GroupID");
        }
    }

    private string _groupName;
    public string GroupName
    {
        get
        {
            return _groupName;
        }

        set
        {
            _groupName = value;
            OnPropertyChanged("GroupName");
        }
    }

    private string _correspondingEffect;
    public string CorrespondingEffect
    {
        get
        {
            return _correspondingEffect;
        }

        set
        {
            _correspondingEffect = value;
            OnPropertyChanged("CorrespondingEffect");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

我的ViewModel中的更改:

我刪除了屬性GroupsCollection及其所有引用,並添加了一個名為GroupIDAndNamesWithCorrespondingEffects的新屬性,如下所示:

private ObservableCollection<GroupIDAndNameWithCorrespondingEffect> _groupIDAndNamesWithCorrespondingEffects;
public ObservableCollection<GroupIDAndNameWithCorrespondingEffect> GroupIDAndNamesWithCorrespondingEffects
{
    get
    {
        return _groupIDAndNamesWithCorrespondingEffects;
    }
    set
    {
        _groupIDAndNamesWithCorrespondingEffects = value;
        OnPropertyChanged("GroupIDAndNamesWithCorrespondingEffects");
    }
}

在構造函數中:

List<GroupIDAndNameWithCorrespondingEffect> _GroupIDAndNamesWithCorrespondingEffects = (
                                                                                                 from g in sampleDBContext.Groups
                                                                                                 select new GroupIDAndNameWithCorrespondingEffect
                                                                                                 {
                                                                                                     GroupID = g.GroupID,
                                                                                                     GroupName = g.GroupName,
                                                                                                     CorrespondingEffect = g.Effect.Effect1
                                                                                                 }
                                                                                             ).ToList();

            GroupIDAndNamesWithCorrespondingEffects
                = new ObservableCollection<GroupIDAndNameWithCorrespondingEffect>(
                                                                                _GroupIDAndNamesWithCorrespondingEffects.Where
                                                                                    (
                                                                                        u => !GetAllChildren(25)
                                                                                                .Select(x => x.GroupID)
                                                                                                .Contains(u.GroupID)
                                                                                    ).ToList()
                                                                            );

在我的MainWindow.xaml中,我添加了如下資源:

<Window.Resources>
    <CollectionViewSource x:Key="GroupNamesWithCorrespondingEffectsCollection" Source="{Binding GroupIDAndNamesWithCorrespondingEffects}" />    
</Window.Resources>

內部網格資源:

    <Grid.Resources>

        <CompositeCollection x:Key="Items">
            <ComboBoxItem IsEnabled="False" Background="#FF2A2A2A" Foreground="White">
                <Grid TextElement.FontWeight="Bold" >
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition SharedSizeGroup="A" />
                        <ColumnDefinition Width="50" />
                        <ColumnDefinition SharedSizeGroup="B" />
                    </Grid.ColumnDefinitions>
                    <Grid.Children>
                        <TextBlock Grid.Column="0" Text="Group Name" />
                        <TextBlock Grid.Column="2" Text="Effect" />
                    </Grid.Children>
                </Grid>
            </ComboBoxItem>
            <CollectionContainer Collection="{Binding Source={StaticResource GroupNamesWithCorrespondingEffectsCollection}}" />
        </CompositeCollection>

        <DataTemplate DataType="{x:Type self:GroupIDAndNameWithCorrespondingEffect}">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition SharedSizeGroup="A" />
                    <ColumnDefinition Width="50" />
                    <ColumnDefinition SharedSizeGroup="B" />
                </Grid.ColumnDefinitions>
                <Grid.Children>
                    <TextBlock Grid.Column="0" Text="{Binding GroupName}" />
                    <TextBlock Grid.Column="2" Text="{Binding CorrespondingEffect}" />
                </Grid.Children>
            </Grid>
        </DataTemplate>

    </Grid.Resources>

然后將ComboBox的ItemsSource更改為ItemsSource =“ {DynamicResource Items}”。

問題 :

當我運行程序時,ComboBox會正確顯示所有項目。 此外,將顯示兩列帶有標題。 它的工作正常,但是當我按EnterTAB時 ,焦點仍保留在同一單元格中,並且comboBox的文本顯示GroupIDAndNameWithCorrespondingEffect的命名空間

這是問題的圖像:

在此處輸入圖片說明

樣品:

如果有人要檢查樣品,則可在此處獲得 數據庫文件在這里可用。

得到它了!!!!

我在Grid中使用key="Items"聲明了資源。 因此,當我在DataGrid的PreviewKeyDown事件中檢查ComboBox.SelectedIndex時,它給我-1 ,因此我的邏輯異常。 另外,這時我得到ComboBox.Items.Count = 0

因此,我只是更改了資源聲明的位置。 我的意思是我刪除了Grid.Resources Section並在ComboBox.Resources section編寫了相同的代碼。 現在工作正常。 現在在PreviewKeyDown of DataGrid ,我得到了SelectedIndex of the ComboBox的期望SelectedIndex of the ComboBox以及ComboBox.Items.Count is equal to the Count in Source

我不知道為什么會這樣? 因為我將其用作DynamicResource所以即使它在Grid.Resources部分中聲明了,我也希望它能正常工作。

也許……也許您的組合框只需要IsEditable = false。 IsEditable = True導致組合框顯示名稱空間而不是文本。

解決此問題的一種方法是在http://www.shujaat.net/2010/08/wpf-editable-combobox-with-datatemplate.html中

TextSearch.TextPath="GroupName"

另一種方法是向ComboBox的ItemTemplate提供一個DataTemplate

<ComboBox ItemTemplate="{StaticResource myDataTemplate}"/>

暫無
暫無

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

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