【发布时间】:2014-02-28 06:12:24
【问题描述】:
首先解释一下我想做什么。
我正在创建一个过滤器,用于显示具有相同实体类型 (ProvisionalOrder) 的多个对象。该实体有一个属性 DateTime Date。有了这个日期,我想过滤。例如:如果用户点击日期 X ,视图将显示所有日期为 X 的临时订单。
对于每个日期,我都会在视图中创建一个按钮。我想像这样设置按钮的背景: 橙红色 = 已激活。 LightSkyBlue = 未激活。
当我启动程序时,背景很好。但是,如果我单击该按钮,则背景不会变为应有的颜色。
数据触发器有问题?
查看:
<!-- Grid with date buttons -->
<ItemsControl Grid.Row="1" ItemsSource="{Binding DatePairs}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="{Binding Path=Key}"
Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type this:ProvisionalOrderSelecterView} },
Path=DataContext.FilterDateCommand}"
CommandParameter="{Binding Path=Key}">
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Value}" Value="True">
<Setter Property="Background" Value="OrangeRed"/>
</DataTrigger>
<DataTrigger Binding="{Binding Path=Value}" Value="False">
<Setter Property="Background" Value="LightSkyBlue"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<!-- End Grid with date buttons -->
代码隐藏视图:
public partial class ProvisionalOrderSelecterView : UserControl
{
public ProvisionalOrderSelecterView(ProvisionalOrderSelecterViewModel provisionalOrderSelecterViewModel)
{
InitializeComponent();
this.DataContext = provisionalOrderSelecterViewModel;
}
}
视图模型:
public class ProvisionalOrderSelecterViewModel : INotifyPropertyChanged
{
private RelayCommand<DateTime> filterDateCommand;
private SortedDictionary<DateTime, bool> datePairs;
private ObservableCollection<ProvisionalOrder> provisionalOrders;
public ProvisionalOrderSelecterViewModel(ObservableCollection<ProvisionalOrder> provisionalOrders)
{
this.ProvisionalOrders = provisionalOrders;
if(datePairs == null)
datePairs = new SortedDictionary<DateTime, bool>();
FillDates();
datePairs.Add(DateTime.Now.Date, true);
}
void FillDates()
{
var copy = datePairs;
datePairs = new SortedDictionary<DateTime, bool>();
foreach (var provisionalOrder in this.provisionalOrders.Where(provisionalOrder => !datePairs.ContainsKey(provisionalOrder.Date.Date)))
{
datePairs.Add(provisionalOrder.Date.Date, copy.ContainsKey(provisionalOrder.Date.Date) && copy[provisionalOrder.Date.Date]);
}
}
private void ProvisionalOrders_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
OnPropertyChanged("ProvisionalOrders");
}
public ObservableCollection<ProvisionalOrder> ProvisionalOrders
{
get { return this.provisionalOrders; }
set
{
this.provisionalOrders = value;
this.provisionalOrders.CollectionChanged += ProvisionalOrders_CollectionChanged;
OnPropertyChanged("ProvisionalOrders");
}
}
public SortedDictionary<DateTime, bool> DatePairs
{
get { return this.datePairs; }
set
{
this.datePairs = value;
OnPropertyChanged("DatePairs");
}
}
public ICommand FilterDateCommand
{
get { return this.filterDateCommand ?? (this.filterDateCommand = new RelayCommand<DateTime>(FilterDate)); }
}
void FilterDate(DateTime date)
{
datePairs[date] = !datePairs[date];
OnPropertyChanged("DatePairs");
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
#endregion // INotifyPropertyChanged Members
}
编辑:我做了一个混乱的解决方案。如果有人仍然知道答案,如果您能与 stackoverflow 分享,我将不胜感激。
回答: 在我的按钮上,我做了一个点击事件。
private void DateButton_Click(object sender, RoutedEventArgs e)
{
var button = sender as Button;
if (button != null)
{
var background = button.Background as SolidColorBrush;
if (background != null)
{
button.Background = background.Color.Equals(Colors.OrangeRed)
? new SolidColorBrush(Colors.LightSkyBlue)
: new SolidColorBrush(Colors.OrangeRed);
}
}
e.Handled = true;
}
【问题讨论】:
-
这里有两个问题。首先,当您绑定到
Dictionary以有效地绑定到IEnumerable<KeyValuePair<DateTime, bool>>和KeyValuePair是结构,所以值类型,因此 WPF 将复制它的值而不是保持对它的引用。它也没有实现INotyfyPropertyChanged,你不能/不能改变它的Value
标签: wpf mvvm background datatrigger