0

我正在使用 Prism 6 创建我的应用程序,并且我需要根据日期为 DataGridRows 的背景着色。我开始创建一个 Blend SDK 触发器来接受两个参数:MinDate 和 MaxDate。然后该操作将设置背景颜色。但是,在使用触发器时,我遇到了障碍。它在集合中不被接受,当我使用 DataTemplate 时,我似乎无法让触发器执行。

这是触发器的代码。除了调用操作之外,它实际上并没有做任何事情,因为我想确保它在编码逻辑以检查日期之前正在执行。

public class AnniversaryTrigger: TriggerBase<DataGridRow>
{
    public DateTime MaxDate
    {
        get { return (DateTime)GetValue(MaxDateProperty); }
        set { SetValue(MaxDateProperty, value); }
    }

    public DateTime MinDate
    {
        get { return (DateTime)GetValue(MinDateProperty); }
        set { SetValue(MinDateProperty, value); }
    }

    protected override void OnAttached()
    {
        AssociatedObject.Loaded += OnLoaded;
        AssociatedObject.Unloaded += OnUnloaded;
    }

    protected override void OnDetaching()
    {
        AssociatedObject.Loaded -= OnLoaded;
        AssociatedObject.Unloaded -= OnUnloaded;
    }

    private void OnLoaded(object sender, System.Windows.RoutedEventArgs e)
    {
        AssociatedObject.DataContextChanged += OnDataContextChanged;
        Refresh();
    }

    private void OnUnloaded(object sender, System.Windows.RoutedEventArgs e)
    {
        AssociatedObject.DataContextChanged -= OnDataContextChanged;
    }

    private void Refresh()
    {
        base.InvokeActions(null);
    }

    private void OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
        Refresh();
    }

    #region Dependency Properties
    public static readonly DependencyProperty MaxDateProperty =
        DependencyProperty.Register("MaxDate", typeof(DateTime), typeof(AnniversaryTrigger), new PropertyMetadata(null));

    public static readonly DependencyProperty MinDateProperty =
        DependencyProperty.Register("MinDate", typeof(DateTime), typeof(AnniversaryTrigger), new PropertyMetadata(null));
    #endregion
}

DataTemplate 如下,并附加到 DataGrid ItemTemplate。

<UserControl.Resources>
    <DataTemplate x:Key="AnniversaryTemplate">
        <DataGridRow>
            <i:Interaction.Triggers>
                <b:AnniversaryTrigger MinDate="{Binding MinDate}" 
                                      MaxDate="{Binding MaxDate}" >
                    <ei:ChangePropertyAction PropertyName="Background">
                        <ei:ChangePropertyAction.Value>
                            <SolidColorBrush Color="Yellow"/>
                        </ei:ChangePropertyAction.Value>
                    </ei:ChangePropertyAction>
                </b:AnniversaryTrigger>
            </i:Interaction.Triggers>
        </DataGridRow>
    </DataTemplate>
</UserControl.Resources>

这是数据网格:

<DataGrid ItemsSource="{Binding FalseAlarmHistory}" AutoGenerateColumns="False" IsReadOnly="True" ItemTemplate="{DynamicResource AnniversaryTemplate}" >
        <DataGrid.Columns>
            <DataGridTextColumn Header="Incident ID" 
                                Binding="{Binding IncidentID}" />
            <DataGridTextColumn Header="Incident Date" 
                                Binding="{Binding IncidentDate, StringFormat=d}" />
            <DataGridTextColumn Header="Incident Time" 
                                Binding="{Binding IncidentTime}" />
            <DataGridTextColumn Header="Notes" 
                                Binding="{Binding Notes}" />
        </DataGrid.Columns>
    </DataGrid>

任何指导表示赞赏。

事件历史视图模型:

public class FalseAlarmHistoryViewModel : ValidatingBindableBase, IConfirmNavigationRequest
{
    private IFalseAlarmService _service;
    private ICustomerService _custsvc;

    private string _title;
    private IEventAggregator _eventAggregator;

    public string Title { get => _title; set => SetProperty(ref _title, value); }

    public FalseAlarmHistoryViewModel(IFalseAlarmService service, ICustomerService custsvc, IEventAggregator eventAggregator)
    {
        _service = service;
        _custsvc = custsvc;
        _eventAggregator = eventAggregator;
        Title = "False Alarms History";

        _eventAggregator.GetEvent<PermitSelectedChangedEvent>().Subscribe(PermitIdChanged);
    }

    //todo Color DataGrid Rows based on the anniversary year the false alarm occurred.  
    // See https://stackoverflow.com/questions/14997250/datagrid-row-background-color-mvvm
    // Add unmapped item to the FalseAlarmHistory entity that returns the year based on the anniversary year. 0 = current year, 1 = 1 year ago, etc.
    // Translate the year number into a color that will be used on the DataGrid row.  Make the color configurable (in app.config at least).

    //todo Initial sort should be most recent first.
    private void PermitIdChanged(int obj)
    {
        FalseAlarmHistory = new ListCollectionView(_service.GetFalseAlarmHistoryByPermitId(_custsvc.CurrentPermitId).ToList());
        RaisePropertyChanged(nameof(FalseAlarmHistory));
    }

    public void ConfirmNavigationRequest(NavigationContext navigationContext, Action<bool> continuationCallback)
    {
        continuationCallback(true);
    }

    public void OnNavigatedTo(NavigationContext navigationContext)
    {
        FalseAlarmHistory = new ListCollectionView(_service.GetFalseAlarmHistoryByPermitId(_custsvc.CurrentPermitId).ToList());
        RaisePropertyChanged(nameof(FalseAlarmHistory));
    }

    public bool IsNavigationTarget(NavigationContext navigationContext)
    {
        return true;
    }

    public void OnNavigatedFrom(NavigationContext navigationContext)
    {
    }

    #region Commands
    #endregion
    #region Event Handlers
    #endregion
    #region Bound Controls
    public ICollectionView FalseAlarmHistory { get; private set; }


    #endregion
    #region Bound Commands
    #endregion
}
4

1 回答 1

0

所以,我在想的是,您向事件模型添加一个属性,该属性将根据事件和周年日期进行计算。听上去,您必须以某种方式将周年纪念日纳入事件模型。您可以从您的数据中执行此操作,或者通过属性、构造函数、函数等将其传递给事件模型。

假设您调用 propertyIncidentAgeBucket和 make of type AgeBucket

// Inside Incident Model
public AgeBucket IncidentAgeBucket { get {
    // AgeBucket calculation logic goes here
    // Check to make sure you have an anniversary date first...
    // There are a few ways to approach setting this value, use one that you are comfortable with 
    }
}

// New enumeration to use (name these something more to your liking)
public enum AgeBucket{
    OneYear,
    TwoYear,
    ThreeYear
}

因此,如果日期在周年日期的年份内,则返回值IncidentAgeBucketAgeBucket.OneYear两年时返回AgeBucket.TwoYear,等等。

在 XAML 中,RowStyle根据属性中的值添加一个:

<DataGrid x:Name="IncidentList" ItemsSource="{Binding Incidents}" ...>
    <DataGrid.Columns>
        <DataGridTextColumn Header="Incident Number" Binding="{Binding IncidentNumber}"/>
        ...
    </DataGrid.Columns>
    <DataGrid.RowStyle>
        <Style TargetType="DataGridRow">
            <Style.Triggers>
                <DataTrigger Binding="{Binding IncidentAgeBucket}" Value="{x:Static local:AgeBucket.OneYear}">
                    <Setter Property="Background" Value="LightGreen"></Setter>
                </DataTrigger>
                <DataTrigger Binding="{Binding IncidentAgeBucket}" Value="{x:Static local:AgeBucket.TwoYear}">
                    <Setter Property="Background" Value="LightBlue"></Setter>
                </DataTrigger>
                <DataTrigger Binding="{Binding IncidentAgeBucket}" Value="{x:Static local:AgeBucket.ThreeYear}">
                    <Setter Property="Background" Value="LightPink"></Setter>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </DataGrid.RowStyle>
</DataGrid>

您可能需要稍微尝试一下{x:Static local:AgeBucket.OneYear}语法。本地命名空间可能不是您使用的。如果你最终嵌套了枚举,那么你还需要做其他事情才能让它工作。一个看似很好的参考

我希望这会让你对触发路线以外的方向有所了解。这对我来说似乎更直接。

如果这太离谱了,请告诉我,我会放弃这个答案。评论太多了!希望这可以帮助。

于 2017-07-31T22:08:33.743 回答