[英]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會正確顯示所有項目。 此外,將顯示兩列帶有標題。 它的工作正常,但是當我按Enter或TAB時 ,焦點仍保留在同一單元格中,並且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.