Я пытался научиться использовать Dispatches в Windows Presentation Foundation уже около 4 часов, и есть проблема, которую я никак не могу решить, независимо от того, сколько я гуглю.
У меня есть эта простая программа, которая рассчитывает процент прохождения пути через установленные сроки, например, 19% пути с 5 января по 31 марта.
Независимо от того, что я пытаюсь Я пытался написать класс DayChangeNotification, но это продолжало вызывать у меня проблемы, затем попытался использовать пакет Nuget для настройки задачи планирования для окна, но решил, что это сокращает углы, поэтому я вернулся к слегка модифицированному MidnightNotifier, который я нашел на некоторый стекопоток, вот мой код для MainWindow - я не уверен на 100% в том, как работать с событиями, происходящими из полностью синхронных линейных игр, поэтому, пожалуйста, будьте осторожны :)
using System;
using System.Windows;
using System.Windows.Controls;
namespace DateMeter
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DateTime StartDate = new DateTime(2020, 1, 6), EndDate = new DateTime(2020, 3, 30); //Made a global for these as an attempt
WindowStartupLocation = WindowStartupLocation.Manual;
Left = SystemParameters.WorkArea.Width - Width - (50 * (SystemParameters.WorkArea.Width / 2560)); //Don't know if this ratio
Top = SystemParameters.WorkArea.Height - Height - (50 * (SystemParameters.WorkArea.Height / 1440)); //code works yet.
ProgressBar timeToDate = pbDate;
pbDate.Value = ((DateTime.Now.Date - StartDate).TotalDays / (EndDate - StartDate).TotalDays);
pbDate.Maximum = 1; //Value between 0-1 rather than 0-100
MidnightNotifier.DayChanged += (o, e) =>
{
Dispatcher.Invoke(delegate ()
{
pbDate.Value = ((DateTime.Now.Date - StartDate).TotalDays / (EndDate - StartDate).TotalDays);
});
};
}
}
}
и вот мой Класс MidnightNotifier,
using System;
using System.Timers;
namespace DateMeter
{
static class MidnightNotifier
{
private static readonly Timer timer;
static MidnightNotifier()
{
timer = new Timer(GetSleepTime());
timer.Elapsed += (s, e) =>
{
OnDayChanged();
timer.Interval = GetSleepTime();
};
timer.Start();
SystemEvents.TimeChanged += OnSystemTimeChanged;
}
private static double GetSleepTime()
{
var midnightTonight = DateTime.Today.AddDays(1);
var differenceInMilliseconds = (midnightTonight - DateTime.Now).TotalMilliseconds;
return differenceInMilliseconds;
}
private static void OnDayChanged()
{
var handler = DayChanged;
if (handler != null)
handler(null, null);
}
private static void OnSystemTimeChanged(object sender, EventArgs e)
{
timer.Interval = GetSleepTime();
}
public static event EventHandler<EventArgs> DayChanged;
}
}
Если вам нужна дополнительная информация, дайте мне знать, спасибо за любую помощь, ребята :)
Редактировать: Мой плохой это полностью сорвалось с ума, извините, ребята
xmlns:local="clr-namespace:DateMeter"
mc:Ignorable="d"
Height="150" Width="150" WindowStyle="None"
AllowsTransparency="True" Background="Transparent">
<Window.Resources>
<local:ProgressToAngleConverter x:Key="ProgressConverter"/>
<Style TargetType="{x:Type ProgressBar}" x:Key="ProgressBarStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ProgressBar}">
<Grid>
<Ellipse Stroke="Black" Fill="#969696"/>
<Ellipse Stroke="Black" Margin="5" Fill="#2B2B2B"/>
<local:Arc StrokeThickness="4" Stroke="#2ce64e" Margin="1">
<local:Arc.StartAngle>
<MultiBinding Converter="{StaticResource ProgressConverter}">
<Binding Path="Minimum" RelativeSource="{RelativeSource TemplatedParent}"/>
<Binding Path="." RelativeSource="{RelativeSource TemplatedParent}"/>
</MultiBinding>
</local:Arc.StartAngle>
<local:Arc.EndAngle>
<MultiBinding Converter="{StaticResource ProgressConverter}">
<Binding Path="Value" RelativeSource="{RelativeSource TemplatedParent}"/>
<Binding Path="." RelativeSource="{RelativeSource TemplatedParent}"/>
</MultiBinding>
</local:Arc.EndAngle>
</local:Arc>
<TextBlock Text="{Binding Value, RelativeSource={RelativeSource TemplatedParent}, StringFormat={}{0:0.0%}}"
Foreground="{TemplateBinding Background}" VerticalAlignment="Center" HorizontalAlignment="Center"
FontSize="24" FontWeight="Light"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Border CornerRadius="90" BorderBrush="#2B2B2B" BorderThickness="4" Background="#838383">
<Grid>
<Viewbox>
<ProgressBar Name="pbDate" Style="{StaticResource ProgressBarStyle}"
Height="100" Width="100"/>
</Viewbox>
</Grid>
</Border>
</Window>
Вот мой xaml для MainWindow (только у меня есть окно)
Проблема, которая продолжает возникать, - это classi c 'Вызывающий поток не может получить доступ к этому объекту, потому что другой поток владеет им. '