这是我的关注。我有两个有时必须同时触发的datePickers(我选择了一个代理,得到了它的开始日期和结束日期)。
我有一个方法可以根据日期检索计划,问题是它需要同时使用开始日期+结束日期+正常触发器(当我选择座席时,会显示其默认计划。 ) 因此,结果可以同时提供给我一些信息(我收到一条错误消息“无计划” +一项落后的计划,这毫无意义)
这是代码:
<DatePicker Grid.Column="1" Name="DatePickerStart"
Grid.Row="5"
Margin="40,5"
Height="25"
DisplayDateEnd="{Binding DateEnd}"
SelectedDate="{Binding DateStart}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectedDateChanged">
<i:InvokeCommandAction Command="{Binding LoadMatrice}" CommandParameter="{Binding SelectedDate, RelativeSource={RelativeSource AncestorType={x:Type DatePicker}}}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</DatePicker>
<TextBlock Grid.Row="4"
Grid.Column="2"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="16"
Text="Date Fin:"/>
<DatePicker Grid.Column="2" Name="DatePickerEnd"
Grid.Row="5"
Margin="40,5"
Height="25"
DisplayDateStart="{Binding DateStart}"
SelectedDate="{Binding DateEnd}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectedDateChanged">
<i:InvokeCommandAction Command="{Binding LoadMatrice}" CommandParameter="{Binding SelectedDate, RelativeSource={RelativeSource AncestorType={x:Type DatePicker}}}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</DatePicker>
VM:
private DateTime _DateDebut;
public DateTime DateDebut
{
get
{
return _DateDebut;
}
set
{
if (value != _DateDebut)
{
_DateDebut = value;
RaisePropertyChanged(nameof(DateDebut));
}
}
}
private DateTime _DateFin;
public DateTime DateFin
{
get
{
return _DateFin;
}
set
{
if (value != _DateFin)
{
_DateFin = value;
RaisePropertyChanged(nameof(DateFin));
}
}
}
当我在组合框中选择某些内容时:
private string _SelectedResultList;
public string SelectedResultList
{
get
{
return _SelectedResultList;
}
set
{
if (value != _SelectedResultList)
{
_SelectedResultList = value;
//GetIdSelectedResultList();
foreach (var periode in PeriodesModulation)
{
if (value == valueILookingFor)
{
DateStart = periode.Start;
DateEnd = periode.End;
}
}
RaisePropertyChanged(nameof(SelectedResultList));
}
}
}
触发的方法:
LoadMatrice = new RelayCommand(async () =>
{
await GetParametresMatrice();
});
和:
public async Task GetParametresMatrice()
{
ErrorMatrice = null;
if (_SelectedChoiceList != null) // important pour ne pas rechercher avec les dates.today du reset avant qu'on ai fait la demande
{
GetMatricule(matriculeSelectedAgent);
Planning = new ObservableCollection<Planning>(await _dataService.GetPlanning(matriculeSelectedAgent, _dataService.ParamGlobaux.IDEtablissement, DateStart, DateEnd));
GetIdMatrice(Planning);
Matrice = new ObservableCollection<Matrix>(await _dataService.GetMatrice(idMatrice));
}
}
我计算找到的计划的数量,然后:
private void GetIdMatrice(ObservableCollection<Planning> planning)
{
idMatrice = null;
if (planning.Count > 0)
{
if (planning.Any(p => p.IDMatrice == null))
{
ErrorMatrice = $"Pas de matrice trouvées, modification impossible";
}
else if (planning.GroupBy(p => p.IDMatrice).Count() > 1)
{
ErrorMatrice = $"Deux matrices différentes trouvées, modification impossible";
}
else
{
idMatrice = planning.First().IDMatrice;
}
}
else
{
ErrorMatrice = $"Pas de planning trouvé sur cette période.";
}
}
后者,GetParametresMatrice(),重复了几次,这是正常的,但同时又是有问题的。我希望循环一个接一个地完成。
第一次“加载”通过后,一切正常。如果我更改开始日期或结束日期,则时间表将进行调整。实际上,只有当我选择一个计划并且两个日期都已加载时。
编辑:在布局加载期间没有问题,因为“ if(_SelectedChoiceList!= null)”行。 这是我的组合框,非常完美。 问题是当我在组合框中选择一个代理并且StartDate / EndDate同时更改时。
编辑2:
当我显示结果时,我有一个时间表+错误消息。通常这是不可能的,Planning.count不能为> 1 AND <1
有什么提示吗?
谢谢。
答案 0 :(得分:1)
您的主要问题似乎是您的ICommand
实现(RelayCommand
)不同步或无法等待。如果是这样,您本可以等待LoadMatrice
命令。
您将找到一个异步ICommand
实现here的示例。
public class AsyncCommand : IAsyncCommand
{
public event EventHandler CanExecuteChanged;
private bool _isExecuting;
private readonly Func<Task> _execute;
private readonly Func<bool> _canExecute;
private readonly IErrorHandler _errorHandler;
public AsyncCommand(
Func<Task> execute,
Func<bool> canExecute = null,
IErrorHandler errorHandler = null)
{
_execute = execute;
_canExecute = canExecute;
_errorHandler = errorHandler;
}
public bool CanExecute()
{
return !_isExecuting && (_canExecute?.Invoke() ?? true);
}
public async Task ExecuteAsync()
{
if (CanExecute())
{
try
{
_isExecuting = true;
await _execute();
}
finally
{
_isExecuting = false;
}
}
RaiseCanExecuteChanged();
}
public void RaiseCanExecuteChanged()
{
CanExecuteChanged?.Invoke(this, EventArgs.Empty);
}
#region Explicit implementations
bool ICommand.CanExecute(object parameter)
{
return CanExecute();
}
void ICommand.Execute(object parameter)
{
ExecuteAsync().FireAndForgetSafeAsync(_errorHandler);
}
#endregion
}
您可能还想阅读this文章。
但是,即使将命令类型更改为AsyncCommand
,您在XAML中定义的InvokeCommandAction
仍不会调用ExecuteAsync()
方法。您最好自己在视图模型中调用它,或者直接调用async方法。例如,您可以通过为PropertyChanged
事件连接一个异步事件处理程序来做到这一点:
public ViewModel()
{
this.PropertyChanged += async (s, e) =>
{
switch (e.PropertyName)
{
case nameof(DateDebut):
await GetParametresMatrice();
//here the method has completed and you can do whatever you want...
break;
}
};
}
答案 1 :(得分:0)
由于在加载页面布局期间绑定了DateEnd数据和DateStart,因此触发了两次您的事件。同样,当您设置新数据模型时,由于相同的原因,它也会触发两次事件。
您可以重新放置逻辑以允许执行命令方法
from flask import Flask
from flask import send_file
from redis import Redis, RedisError
import os
import socket
Connect to Redis
redis = Redis(host="redis", db=0, socket_connect_timeout=2, socket_timeout=2)
app = Flask(__name__)
@app.route("/")
def hello():
html = " <b>Container Name:</b> {hostname}<br/>"
return html.format(hostname=socket.gethostname()), (send_file('counter.mp4', attachment_filename='counter.mp4')