我有一个自定义控制,以显示与一个ComboBox
内复选框项目。为了实现这一点,我使用了DataTemplate
和CheckBox
。 ComboBox
的ItemSource
使用绑定到包含我的过滤器值的ObserableCollection<FilterValue>
。 FilterValue
是一个实现INotifyPropertyChanged
的自定义类。 CheckBox
的属性Content
和IsChecked
也使用绑定来使用我的列表的值。此控件将用于Silverlight。选中复选框事件触发之前势必收集更新
当我注册Checked
或Unchecked
事件出现的问题。
只要复选框一个改变其状态,如预期的事件被触发,但在这一刻,在绑定列表中的值仍然没有更新。 我看到了什么,而调试的是,Checked
/Unchecked
事件在PropertyChanged
事件FilterValue
之前发射。 这意味着在事件发生的时候,我不能要求列表中的所有活动(选中)过滤器。我能做些什么来实现这一目标?
FilterControl.xaml:
<UserControl
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:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
xmlns:local="clr-namespace:Controls" x:Class="Controls.FilterControl"
mc:Ignorable="d"
d:DesignHeight="45" d:DesignWidth="140">
<StackPanel x:Name="LayoutRoot">
<sdk:Label x:Name="LblFilterDescription" Content="-" />
<ComboBox x:Name="Filter" Width="120" ItemsSource="{Binding AvailableFilters, RelativeSource={RelativeSource FindAncestor, AncestorType=local:FilterControl}}">
<ComboBox.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding Path=Text}" IsChecked="{Binding Path=IsChecked, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Checked="FilterChanged" Unchecked="FilterChanged" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</StackPanel>
</UserControl>
FilterControl.xaml.cs:
public partial class FilterControl : UserControl
{
public delegate void FilterChangedHandler(object sender);
public event FilterChangedHandler OnFilterChanged;
public ObservableCollection<FilterValue> AvailableFilters { get; set; }
public List<string> AppliedFilters
{
get
{
return new List<string>(AvailableFilters.Where(filter => filter.IsChecked).Select(filter => filter.Text));
}
}
public FilterControl()
{
InitializeComponent();
AvailableFilters = new ObservableCollection<FilterValue>();
}
public bool AddFilterValue(string filterValue)
{
bool found = false;
foreach (FilterValue f in AvailableFilters)
{
if (f.Text == filterValue)
{
found = true;
break;
}
}
if (!found)
AvailableFilters.Add(new FilterValue() { IsChecked = false, Text = filterValue });
return found;
}
private void FilterChanged(object sender, RoutedEventArgs e)
{
//Here if I check AvailableFilters, the value is not changed yet.
//PropertyChanged allways fires after this, what makes me unable to
//get all currently applied filters (checked items)...
}
}
FilterValue:
public class FilterValue : INotifyPropertyChanged
{
private bool _IsChecked;
private string _Text;
public bool IsChecked
{
get { return _IsChecked; }
set
{
_IsChecked = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("IsChecked"));
}
}
public string Text
{
get { return _Text; }
set
{
_Text = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Text"));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
我用类似的方法来链接'ObservableCollection',解决一点修修补补后,我的问题。对未来的项目也会很有帮助,谢谢! –