WPF通知MultiConverter绑定集合已更改

时间:2018-09-03 07:08:28

标签: c# wpf observablecollection imultivalueconverter inotifycollectionchanged

我是wpf的新手,我很难理解如何通知多转换器其绑定的集合已更改。我尝试了几种解决方案,但没有任何效果。

我有一个带有多转换器的日历,使我可以根据2 Observablecollection更改calendardaybutton背景。 (好吧,如果我在应用datacontext之前将数据手动放入集合中,我会看到彩色的日子。)

当用户单击日历时,所选日期将添加到其中一个集合中。

我已经检查过,新日期已正确添加到集合中,但是日历上没有任何变化(单击的calendardaybutton背景应该会变化)。

这是我的XAML:

 <Window.Resources>
    <local:DateConverter x:Key="dateConverter" />
    <local:MyViewModel x:Key="myViewModel" />
</Window.Resources>

<Grid>
    <Calendar x:Name="MyCal" 
              SelectionMode="MultipleRange" 
              SelectedDatesChanged="OnSelectedDatesChanged">
        <Calendar.CalendarDayButtonStyle>
            <Style TargetType="CalendarDayButton">
                <Setter Property="Background" >
                    <Setter.Value>
                        <MultiBinding Converter="{StaticResource dateConverter}">
                            <Binding/>
                            <Binding Source="{StaticResource myViewModel}" Path="MyHolidayCollection"  UpdateSourceTrigger="PropertyChanged"/>
                            <Binding Source="{StaticResource myViewModel}" Path="ShutDownDateCollection" UpdateSourceTrigger="PropertyChanged"/>
                        </MultiBinding>
                    </Setter.Value>
                </Setter>
            </Style>
        </Calendar.CalendarDayButtonStyle>
    </Calendar>
 </Grid>`

我的DataContext是一个ViewModel,其中包含2个可观察的集合

    public partial class MainWindow : Window
{
    MyViewModel myViewModel;
    public MainWindow()
    {
        myViewModel = new MyViewModel();
        DataContext = myViewModel;

        InitializeComponent();

    }

    private void OnSelectedDatesChanged(object sender, RoutedEventArgs e)
    {
        Calendar c = (Calendar)sender;
        myViewModel.AssignDate(c.SelectedDate);
    }
}

这是我的ViewModel(继承自ViewModelBase,实现了INotifyPropertyChanged)

public class MyViewModel:ViewModelBase
{
    private ObservableCollection<DateTime?> _holidayDateCollection;
    public ObservableCollection<DateTime?> HolidayDateCollection
    {
        get { return _holidayDateCollection; }
        set
        {
            _holidayDateCollection = value;
            OnPropertyChanged("HolidayDateCollection");
          }
    }

    private ObservableCollection<DateTime?> _shutDownDateCollection;
    public ObservableCollection<DateTime?> ShutDownDateCollection
    {
        get { return _holidayDateCollection; }
        set
        {
            _holidayDateCollection = value;
            OnPropertyChanged("ShutDownDateCollection");
        }
    }

    public MyViewModel()
    {
        HolidayDateCollection = new ObservableCollection<DateTime?>();
        ShutDownDateCollection = new ObservableCollection<DateTime?>();
    }


    public void AssignDate(DateTime? date)
    {
       HolidayDateCollection.Add(date);
    }

这是我的多转换器

public class DateConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        SolidColorBrush s = new SolidColorBrush(Colors.LightBlue);
        SolidColorBrush s1 = new SolidColorBrush(Colors.Yellow);
        SolidColorBrush s2 = new SolidColorBrush(Colors.Red);

        if (((ObservableCollection<DateTime?>)values[1]).Contains((DateTime?)values[0])) { return s1; }
        if (((ObservableCollection<DateTime?>)values[2]).Contains((DateTime?)values[0])) { return s2; }

        return s;//normal day
    }



    public object[] ConvertBack(object value, Type[] targetTypes,
           object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotSupportedException("Cannot convert back");
    }
}

我尝试了很多解决方案(为了清除此处的代码而删除了这些解决方案),但似乎无济于事。

任何帮助或建议都将不胜感激,我已经呆了好几天了。谢谢。

1 个答案:

答案 0 :(得分:2)

您引用的是两个完全不同的<Window.Resources> <local:DateConverter x:Key="dateConverter" /> <local:MyViewModel x:Key="myViewModel" /> </Window.Resources> 实例,这就是您面临此问题的原因。

实例1 :(在xml中)

myViewModel = new MyViewModel();
DataContext = myViewModel;

实例2 :(在文件后面的代码中)

MyViewModel

要解决此问题,请从任一实例更改<Window.Resources> <local:DateConverter x:Key="dateConverter" /> </Window.Resources> <Grid> <Calendar x:Name="MyCal" SelectionMode="MultipleRange" SelectedDatesChanged="OnSelectedDatesChanged"> <Calendar.CalendarDayButtonStyle> <Style TargetType="CalendarDayButton"> <Setter Property="Background" > <Setter.Value> <MultiBinding Converter="{StaticResource dateConverter}"> <Binding /> <Binding RelativeSource="{RelativeSource AncestorType=Window, Mode=FindAncestor}" Path="DataContext.HolidayDateCollection" UpdateSourceTrigger="PropertyChanged"/> <Binding RelativeSource="{RelativeSource AncestorType=Window, Mode=FindAncestor}" Path="DataContext.ShutDownDateCollection" UpdateSourceTrigger="PropertyChanged"/> </MultiBinding> </Setter.Value> </Setter> </Style> </Calendar.CalendarDayButtonStyle> </Calendar> </Grid> 实例。例如,删除表格xaml后,您的代码将如下所示:

function totalTrackLenght($tracklenght){
    global $row, $data, $tracklenght;
    foreach ($data->results as $row) {
        if(!empty($row->trackTimeMillis)){
            $tracklenght += $row->trackTimeMillis;
        }
    }
    return $tracklenght;
}