转换器不适用于矩形填充属性

本文关键字:填充 属性 不适用 适用于 转换器 | 更新日期: 2023-09-27 18:32:46

我在布尔值(Fill="{Binding Path=IsSelected, Converter={StaticResource rectangleFillConverter}}")上绑定了Rectangle Fill属性,它抛出了一个空异常。我检查了属性(已选择)的值不为空。当我从填充属性中删除转换器时,它可以工作。这是我的代码:

XAML

<Rectangle Width="{Binding Duration}" Height="20" Tag="{Binding .}" IsEnabled="{Binding Path=IsEnabled}" Fill="{Binding Path=IsSelected, Converter={StaticResource rectangleFillConverter}}" ToolTip="{Binding Path=Shift}" MouseDown="LabelShift_MouseDown"></Rectangle>

转炉

public class RectangleControlFillConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            SolidColorBrush brush; 
            bool b= (bool)value;
            if (b)
                brush = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#5C8FFF"));
            else
                brush = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#73E34D"));
            return brush;
        }
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

静态资源

<converters:RectangleControlFillConverter x:Key="rectangleFillConverter"/>

财产

private bool _isSelected;
        public bool IsSelected
        {
            get { return _isSelected; }
            set 
            { 
                _isSelected = value;
                OnPropertyChanged("IsSelected");
            }
        }

项目控制矩形的位置,此转换器Converter={StaticResource timeToPositionConverter}}"

工作
<ItemsControl Name="icSchedule" ItemsSource="{Binding .}" Grid.Row="1" Grid.Column="1">
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <StackPanel Orientation="Horizontal" Margin="0"/>
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                                <ItemsControl ItemsSource="{Binding Path=icw}" Tag="{Binding .}" Margin="0,10,0,0"><!--Margin="3"Grid.Row="1" Grid.Column="1"  Background="DarkGray" BorderThickness="1" BorderBrush="White"-->
                                <ItemsControl.ItemsPanel>
                                    <ItemsPanelTemplate>
                                        <Canvas IsItemsHost="True" />
                                    </ItemsPanelTemplate>
                                </ItemsControl.ItemsPanel>
                                <ItemsControl.ItemContainerStyle>
                                    <Style TargetType="{x:Type ContentPresenter}">
                                        <Setter Property="Canvas.Left" Value="{Binding Path=Start, Converter={StaticResource timeToPositionConverter}}" />
                                        <Setter Property="Canvas.Top" Value="{Binding Path=Index}" />
                                    </Style>
                                </ItemsControl.ItemContainerStyle>
                                <ItemsControl.ItemTemplate>
                                    <DataTemplate DataType="TimeLineEntry">
                                        <Border BorderThickness="1" BorderBrush="DarkGray">
                                                <Rectangle Width="{Binding Duration}" Height="20" Tag="{Binding .}" IsEnabled="{Binding Path=IsEnabled}" Fill="{Binding Path=IsSelected, Converter={StaticResource rectangleFillConverter}}" ToolTip="{Binding Path=Shift}" MouseDown="LabelShift_MouseDown"> 
                                             </Rectangle>                                     
                                        </Border>
                                    </DataTemplate>
                                </ItemsControl.ItemTemplate>
                            </ItemsControl>
                        </DataTemplate> 
                    </ItemsControl.ItemTemplate>
                </ItemsControl>

这是对象上的类是矩形绑定(icw 是该对象的列表)

public partial class ScheduleItem
    {
        public string Shift 
        { 
            get
            {
                //string s = ((DateTime)DateFrom).ToString("dd.MM.yyyy") + " " + ((TimeSpan)TimeFrom).ToString() + " - " + ((DateTime)DateTo).ToString("dd.MM.yyyy") + " " + ((TimeSpan)TimeTo).ToString();
                String s = String.Format("{0}.{1} {2}:{3} - {4}.{5} {6}:{7}", FullDateFrom.Day, FullDateFrom.Month, FullDateFrom.Hour, FullDateFrom.Minute, FullDateTo.Day, FullDateTo.Month, FullDateTo.Hour, FullDateTo.Minute);
                return s;
            }
        }
        private DateTime FullDateFrom
        {
            get
            {
                DateTime dt = ((DateTime)DateFrom).AddHours(((TimeSpan)TimeFrom).Hours).AddMinutes(((TimeSpan)TimeFrom).Minutes);
               return dt;
            }
        }
        private DateTime FullDateTo
        {
            get
            {
                DateTime dt = ((DateTime)DateTo).AddHours(((TimeSpan)TimeTo).Hours).AddMinutes(((TimeSpan)TimeTo).Minutes);
                return dt;
            }
        }
        public string Name { get; set; }
        public DateTime Start { get { return FullDateFrom; } }
        private int index;
        public int Index 
        { 
            get 
            {
                if (CampaignPerson != null)
                    return CampaignPerson.Index;
                else
                    return index;
            }
            set 
            {
                index = value;
            } 
        }
        public int Duration 
        { 
            get 
            { 
                TimeSpan dt = FullDateTo - FullDateFrom;
                return (dt.Days* 92) + (dt.Hours*4); 
            }
        }
        public bool IsEnabled 
        {
            get { return (FullDateFrom > DateTime.Now); }
        }
        private bool _isSelected;
        public bool IsSelected
        {
            get { return _isSelected; }
            set 
            { 
                _isSelected = value;
                OnPropertyChanged("IsSelected");
            }
        }
        #region setters
        partial void OnTimeFromChanged()
        {
            OnPropertyChanged("Duration");
            OnPropertyChanged("Start");
        }
        partial void OnTimeToChanged()
        {
            OnPropertyChanged("Duration");
            OnPropertyChanged("Start");
        }
        partial void OnDateFromChanged()
        {
            OnPropertyChanged("Duration");
            OnPropertyChanged("Start");
        }
        partial void OnDateToChanged()
        {
            OnPropertyChanged("Duration");
            OnPropertyChanged("Start");
        }
        #endregion

    }

视图模型类 icShedule 绑定于此类的集合

public class ScheduleExtension
    {
        public ICollectionView icw {get; set;}
        public ScheduleExtension(CampaignPerson cp)
        {
            campainPerson = cp;
            scheduleItemsList.CollectionChanged += new NotifyCollectionChangedEventHandler(_scheduleItemsList_CollectionChanged);
            icw = CollectionViewSource.GetDefaultView(scheduleItemsList);
            icw.Filter = ScheduleFilter;
        }
        private CampaignPerson _campainPerson;
        public CampaignPerson campainPerson
        {
            get { return _campainPerson; }
            set 
            { 
                _campainPerson = value;
                scheduleItemsList = new ObservableCollection<ScheduleItem>(_campainPerson.ScheduleItem.Where(p=>p.active)); 
            }
        }
        private DateTime _currentDate;
        public DateTime CurrentDate
        {
            get { return _currentDate; }
            set 
            {
                _currentDate = value;
                icw.Refresh();
                //CurrrentScheduleItemsList = new ObservableCollection<ScheduleItem>(scheduleItemsList.Where(p => p.active && ((DateTime)p.DateFrom).Month == CurrentDate.Month && ((DateTime)p.DateFrom).Year == CurrentDate.Year));
                //OnPropertyChanged("CurrentScheduleItemsList");
            }
        }
        public ObservableCollection<ScheduleItem> scheduleItemsList;

        void _scheduleItemsList_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
        }
        private bool ScheduleFilter(object item)
        {
            if (CurrentDate != null)
            {
                ScheduleItem si = item as ScheduleItem;
                return (CurrentDate.Month == ((DateTime)si.DateFrom).Month && CurrentDate.Year == ((DateTime)si.DateFrom).Year);
            }
            return false;
        }
    }

转换器不适用于矩形填充属性

尝试将<DataTemplate DataType="TimeLineEntry">更改为 <DataTemplate DataType="ScheduleItem"> 。也许ScheduleItem是一个TimeLineEntry(你只发布了部分类的一部分),但试试它是否有效。

该问题也可能是由您处理集合的方式引起的。在构造函数中,您说:

icw = CollectionViewSource.GetDefaultView(scheduleItemsList);
icw.Filter = ScheduleFilter;

然后在campainPerson属性中,您说:

scheduleItemsList = new ObservableCollection<ScheduleItem>(_campainPerson.ScheduleItem.Where(p=>p.active));

您必须使用相同的集合对象(通过清除它并添加新项),或者通过创建新ICollectionView并将其分配给icw(因此您必须在创建新ObservableCollection后重复构造函数中的两行)。也试试。

我认为问题不在于转换器,即使删除它时一切正常。这是我的测试应用程序。

MainWindow.xaml

<Window x:Class="MVVMTests.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525"
    xmlns:local="clr-namespace:MVVMTests"
    Background="{StaticResource {x:Static SystemColors.ControlBrushKey}}"
>
<Window.Resources>
    <ResourceDictionary>
        <local:RectangleControlFillConverter x:Key="rectangleFillConverter" />
    </ResourceDictionary>
</Window.Resources>
<Window.DataContext>
    <local:MainWindowViewModel />
</Window.DataContext>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <CheckBox Content="toto" IsChecked="{Binding IsSelected}" />
        <Rectangle Fill="{Binding Path=IsSelected, Converter={StaticResource rectangleFillConverter}}" Grid.Row="1" />
    </Grid>
</Window>

视图模型

namespace MVVMTests
{
    public class MainWindowViewModel : NotificationObject
    {
        private Boolean isSelected;
        public MainWindowViewModel()
        {
            isSelected = true;
        }
        public Boolean IsSelected
        {
            get { return this.isSelected; }
            set
            {
                this.isSelected = value;
                this.RaisePropertyChanged<Boolean>(() => IsSelected);
            }
        }
    }
}

和维特

namespace MVVMTests
{
    [ValueConversion(typeof(Boolean), typeof(SolidColorBrush))]
    public class RectangleControlFillConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            SolidColorBrush brush;
            bool b = (bool)value;
            if (b)
                brush = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#5C8FFF"));
            else
                brush = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#73E34D"));
            return brush;
        }
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

通过这个简单的代码,我们可以看到转换器不是问题(窗口切换丑陋的蓝色/丑陋的绿色),并且绑定工作正常。

这不是解决方案,但这向我们表明问题出在其他地方......

矩形中的转换器仍然不适用于任何属性。

这对我有用Fill="{Binding Path=CurrentColor}"

以及计划项中的此更改

 private bool _isSelected;
        public bool IsSelected
        {
            get { return _isSelected; }
            set 
            { 
                _isSelected = value;
                if(_isSelected)
                    CurrentColor = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#73E34D"));
                else
                    CurrentColor = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#5C8FFF"));
                OnPropertyChanged("CurrentColor");
            }
        }
        private SolidColorBrush _currentColor = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#5C8FFF"));
        public SolidColorBrush CurrentColor
        {
            get { return _currentColor; }
            set { _currentColor = value; }
        }

谢谢大家的时间和建议。