我在bool值(Rectangle
)上绑定Fill
Fill="{Binding Path=IsSelected, Converter={StaticResource rectangleFillConverter}}"
属性,并抛出一个空异常。我检查了属性(IsSelected)的值不为null。当我从Fill属性中删除Converter时,它可以工作。这是我的代码:
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");
}
}
ItemsControl哪里是矩形,此转换器工作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
}
ViewModel类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;
}
}
答案 0 :(得分:1)
尝试将<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
后来自构造函数的行。也试一试。
答案 1 :(得分:0)
我不认为问题来自转换器,即使你删除它时一切正常。这是我的测试应用程序。
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>
ViewModel
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();
}
}
}
使用这个简单的代码,我们可以看到转换器不是问题(窗口开关丑陋蓝/丑绿),绑定工作正常。
这不是一个解决方案,但这告诉我们问题在其他地方......
答案 2 :(得分:0)
矩形转换器仍无法处理任何属性。
这对我有用Fill="{Binding Path=CurrentColor}"
以及ScheduleItem中的此更改
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; }
}
谢谢你们的时间和建议。