ComboBox
の中にチェックボックスを含むアイテムを表示するカスタムコントロールがあります。これを実現するために、CheckBox
とDataTemplate
を使用しました。 ComboBox
のItemSource
は、フィルタ値を含むObserableCollection<FilterValue>
へのバインディングを使用します。 FilterValue
は、INotifyPropertyChanged
を実装するカスタムクラスです。 CheckBox
のContent
とIsChecked
のプロパティは、myリストの値を使用するバインドも使用します。このコントロールはSilverlightで使用されます。自分自身をバインドCheckBoxバインドされたコレクションの更新が行われる前に、チェックされたイベントが発生します
ここに見られるように、正常に動作します:私はChecked
またはUnchecked
イベントを登録するとき
問題が表示されます。
チェックボックスのいずれかが状態を変更すると、イベントは期待どおりに発生しますが、この時点ではバインドされたリストの値は更新されません。 デバッグ中に見たのは、FilterValue
のPropertyChanged
イベントの前に、Checked
/Unchecked
というイベントが発生していることです。 これは、イベントが発生した時点で、すべてのアクティブ(チェックされた)フィルタをリストに尋ねることができないことを意味します。これを達成するために私は何ができますか?
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に同様のアプローチを使用しました。これは、ちょっとしたやりかたの後で私の問題を解決しました。将来のプロジェクトにも非常に役立ちます、ありがとう! –