在WPF項目中,我對DataGrid
進行了一些重新編排DataGridColumnHeaders
,其中顯示ComboBox
每個DataGridColumnHeader
。當用戶從ComboBox
中選擇SelectionChanged
處理程序(在後面的代碼中)時,將使用最新的選擇更新MainWindowViewModel
上的Array
,ColumnOptionViewModel
對象。此時,如果此數組中有任何重複的選擇,則會出現一些代碼,然後在ColumnOptionViewModel
上設置重複的IsDuplicate
布爾屬性。這個想法是,一個DataTrigger
拿起在IsDuplicate
的變化和改變TextBlock
的Background
在ItemTemplate
的DataTemplate
對重複ComboBox
年代到Red
。WPF:DataTrigger not firing
但是,此觸發器未觸發。 IsDuplicate
屬性設置正常,其他一切按預期工作。
有沒有人有任何想法我做錯了什麼?
非常感謝您的任何幫助。
下面是窗口的XAML:
<Window x:Class="TestDataGrid.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:TestDataGrid"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<DataGrid Grid.Row="1" x:Name="dataGrid" ItemsSource="{Binding Records}">
<DataGrid.ColumnHeaderStyle>
<Style TargetType="DataGridColumnHeader">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<StackPanel>
<ComboBox x:Name="cbo"
ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}},Path=DataContext.ColumnOptions}"
SelectionChanged="cbo_SelectionChanged">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock x:Name="txt" Text="{Binding Name}"/>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding ElementName=cbo, Path=SelectedItem.IsDuplicate}">
<Setter TargetName="txt" Property="Background" Value="Red"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</DataGrid.ColumnHeaderStyle>
</DataGrid>
</Grid>
後面的代碼:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new MainWindowViewModel(RecordProvider.GetRecords());
}
private void cbo_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var vm = (MainWindowViewModel)DataContext;
var selectionChangedCombo = (ComboBox)e.Source;
var dataGridColumnHeader = selectionChangedCombo.TemplatedParent as DataGridColumnHeader;
vm.ColumnSelections[dataGridColumnHeader.DisplayIndex] = selectionChangedCombo.SelectedItem as ColumnOptionViewModel;
CheckForDuplicates();
}
private void CheckForDuplicates()
{
var vm = (MainWindowViewModel)DataContext;
var duplicates = vm.ColumnSelections.GroupBy(x => x.Name)
.Where(g => g.Skip(1).Any())
.SelectMany(g => g);
foreach (var option in duplicates)
{
option.IsDuplicate = true;
}
}
}
MainWindowViewModel:
public class MainWindowViewModel : ViewModelBase
{
public ObservableCollection<ColumnOptionViewModel> _columnOptions = new ObservableCollection<ColumnOptionViewModel>();
public ObservableCollection<RecordViewModel> _records = new ObservableCollection<RecordViewModel>();
ColumnOptionViewModel[] _columnSelections = new ColumnOptionViewModel[3];
public MainWindowViewModel(IEnumerable<Record> records)
{
foreach (var rec in records)
{
Records.Add(new RecordViewModel(rec));
}
ColumnOptions.Add(new ColumnOptionViewModel(TestDataGrid.ColumnOptions.ColumnOption1));
ColumnOptions.Add(new ColumnOptionViewModel(TestDataGrid.ColumnOptions.ColumnOption2));
ColumnOptions.Add(new ColumnOptionViewModel(TestDataGrid.ColumnOptions.ColumnOption3));
ColumnSelections[0] = ColumnOptions[0];
ColumnSelections[1] = ColumnOptions[1];
ColumnSelections[2] = ColumnOptions[2];
}
public ObservableCollection<ColumnOptionViewModel> ColumnOptions
{
get { return _columnOptions; }
set { _columnOptions = value; }
}
public ColumnOptionViewModel[] ColumnSelections
{
get { return _columnSelections; }
set { _columnSelections = value; }
}
public ObservableCollection<RecordViewModel> Records
{
get { return _records; }
set { _records = value; }
}
}
ColumnOptionViewModel:
public class ColumnOptionViewModel : ViewModelBase
{
ColumnOptions _colOption;
public ColumnOptionViewModel(ColumnOptions colOption)
{
_colOption = colOption;
}
public string Name
{
get { return _colOption.ToString(); }
}
public override string ToString()
{
return Name;
}
private bool _isDuplicate = false;
public bool IsDuplicate
{
get { return _isDuplicate; }
set
{ _isDuplicate = value;
OnPropertyChanged();
}
}
}
編輯:
ViewModelBase:
public abstract class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
您可以檢查是否改變文本框的任何其他財產datatrigger(如fontWeight設置工作粗體)? – Arie
@Arie,嘗試將FontWeight更改爲Bold,但仍未開始。 – Cleve
你的'OnPropertyChanged'方法是如何實現的?你沒有傳遞屬性的名稱,所以它可能是問題在那裏(有沒有參數的實現,但只是爲了確定)。 – Shadowed