feat: update settings and warning UI

master
tayttt 3 days ago
parent 15b7ac84e8
commit 06cd18d7b2

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1,933 +0,0 @@
<?xml version="1.0"?>
<doc>
<assembly>
<name>OxyPlot.Wpf.Shared</name>
</assembly>
<members>
<member name="T:OxyPlot.Wpf.OxyColorConverter">
<summary>
Converts between <see cref="T:OxyPlot.OxyColor" /> and <see cref="T:System.Windows.Media.Color" />.
</summary>
</member>
<member name="M:OxyPlot.Wpf.OxyColorConverter.Convert(System.Object,System.Type,System.Object,System.Globalization.CultureInfo)">
<summary>
Converts a value.
</summary>
<param name="value">The value produced by the binding source.</param>
<param name="targetType">The type of the binding target property.</param>
<param name="parameter">The converter parameter to use.</param>
<param name="culture">The culture to use in the converter.</param>
<returns>A converted value. If the method returns <c>null</c>, the valid <c>null</c> value is used.</returns>
</member>
<member name="M:OxyPlot.Wpf.OxyColorConverter.ConvertBack(System.Object,System.Type,System.Object,System.Globalization.CultureInfo)">
<summary>
Converts a value.
</summary>
<param name="value">The value that is produced by the binding target.</param>
<param name="targetType">The type to convert to.</param>
<param name="parameter">The converter parameter to use.</param>
<param name="culture">The culture to use in the converter.</param>
<returns>A converted value. If the method returns <c>null</c>, the valid <c>null</c> value is used.</returns>
</member>
<member name="T:OxyPlot.Wpf.ThicknessConverter">
<summary>
Converts from <see cref="T:System.Windows.Thickness" /> to the maximum thicknesses.
</summary>
<remarks>This is used in the <see cref="T:OxyPlot.Wpf.TrackerControl" /> to convert BorderThickness properties to Path.StrokeThickness (double).
The maximum thickness value is used.</remarks>
</member>
<member name="M:OxyPlot.Wpf.ThicknessConverter.Convert(System.Object,System.Type,System.Object,System.Globalization.CultureInfo)">
<summary>
Converts a value.
</summary>
<param name="value">The value produced by the binding source.</param>
<param name="targetType">The type of the binding target property.</param>
<param name="parameter">The converter parameter to use.</param>
<param name="culture">The culture to use in the converter.</param>
<returns>A converted value. If the method returns <c>null</c>, the valid <c>null</c> value is used.</returns>
</member>
<member name="M:OxyPlot.Wpf.ThicknessConverter.ConvertBack(System.Object,System.Type,System.Object,System.Globalization.CultureInfo)">
<summary>
Converts a value.
</summary>
<param name="value">The value that is produced by the binding target.</param>
<param name="targetType">The type to convert to.</param>
<param name="parameter">The converter parameter to use.</param>
<param name="culture">The culture to use in the converter.</param>
<returns>A converted value. If the method returns <c>null</c>, the valid <c>null</c> value is used.</returns>
</member>
<member name="T:OxyPlot.Wpf.ExporterExtensions">
<summary>
Provides extension methods for exporters.
</summary>
</member>
<member name="M:OxyPlot.Wpf.ExporterExtensions.ExportToFile(OxyPlot.IExporter,OxyPlot.IPlotModel,System.String)">
<summary>
Exports the specified <see cref="T:OxyPlot.PlotModel" /> to a file.
</summary>
<param name="exporter">The exporter.</param>
<param name="model">The model to export.</param>
<param name="path">The path to the file.</param>
</member>
<member name="T:OxyPlot.Wpf.MoreColors">
<summary>
Defines additional <see cref="T:System.Windows.Media.Colors" />.
</summary>
</member>
<member name="F:OxyPlot.Wpf.MoreColors.Undefined">
<summary>
The undefined color.
</summary>
</member>
<member name="F:OxyPlot.Wpf.MoreColors.Automatic">
<summary>
The automatic color.
</summary>
</member>
<member name="T:OxyPlot.Wpf.PlotCommands">
<summary>
Provides a standard set of commands for the <see cref="T:OxyPlot.Wpf.PlotViewBase" /> control.
</summary>
</member>
<member name="F:OxyPlot.Wpf.PlotCommands.ResetAxes">
<summary>
Gets the value that represents the "Reset all axes" command.
</summary>
</member>
<member name="T:OxyPlot.Wpf.PlotViewBase">
<summary>
Base class for WPF PlotView implementations.
</summary>
<summary>
Base class for WPF PlotView implementations.
</summary>
<summary>
Base class for WPF PlotView implementations.
</summary>
</member>
<member name="F:OxyPlot.Wpf.PlotViewBase.PartGrid">
<summary>
The Grid PART constant.
</summary>
</member>
<member name="F:OxyPlot.Wpf.PlotViewBase.grid">
<summary>
The grid.
</summary>
</member>
<member name="F:OxyPlot.Wpf.PlotViewBase.plotPresenter">
<summary>
The plot presenter.
</summary>
</member>
<member name="F:OxyPlot.Wpf.PlotViewBase.renderContext">
<summary>
The render context
</summary>
</member>
<member name="F:OxyPlot.Wpf.PlotViewBase.modelLock">
<summary>
The model lock.
</summary>
</member>
<member name="F:OxyPlot.Wpf.PlotViewBase.currentTracker">
<summary>
The current tracker.
</summary>
</member>
<member name="F:OxyPlot.Wpf.PlotViewBase.currentTrackerTemplate">
<summary>
The current tracker template.
</summary>
</member>
<member name="F:OxyPlot.Wpf.PlotViewBase.defaultController">
<summary>
The default plot controller.
</summary>
</member>
<member name="F:OxyPlot.Wpf.PlotViewBase.isInVisualTree">
<summary>
Indicates whether the <see cref="T:OxyPlot.Wpf.PlotViewBase"/> was in the visual tree the last time <see cref="M:OxyPlot.Wpf.PlotViewBase.Render"/> was called.
</summary>
</member>
<member name="F:OxyPlot.Wpf.PlotViewBase.mouseDownPoint">
<summary>
The mouse down point.
</summary>
</member>
<member name="F:OxyPlot.Wpf.PlotViewBase.overlays">
<summary>
The overlays.
</summary>
</member>
<member name="F:OxyPlot.Wpf.PlotViewBase.zoomControl">
<summary>
The zoom control.
</summary>
</member>
<member name="M:OxyPlot.Wpf.PlotViewBase.#cctor">
<summary>
Initializes static members of the <see cref="T:OxyPlot.Wpf.PlotViewBase" /> class.
</summary>
</member>
<member name="M:OxyPlot.Wpf.PlotViewBase.#ctor">
<summary>
Initializes a new instance of the <see cref="T:OxyPlot.Wpf.PlotViewBase" /> class.
</summary>
</member>
<member name="P:OxyPlot.Wpf.PlotViewBase.ActualController">
<summary>
Gets the actual PlotView controller.
</summary>
<value>The actual PlotView controller.</value>
</member>
<member name="P:OxyPlot.Wpf.PlotViewBase.OxyPlot#IView#ActualController">
<inheritdoc/>
</member>
<member name="P:OxyPlot.Wpf.PlotViewBase.ActualModel">
<summary>
Gets the actual model.
</summary>
<value>The actual model.</value>
</member>
<member name="P:OxyPlot.Wpf.PlotViewBase.OxyPlot#IView#ActualModel">
<inheritdoc/>
</member>
<member name="P:OxyPlot.Wpf.PlotViewBase.ClientArea">
<summary>
Gets the coordinates of the client area of the view.
</summary>
</member>
<member name="P:OxyPlot.Wpf.PlotViewBase.TrackerDefinitions">
<summary>
Gets the tracker definitions.
</summary>
<value>The tracker definitions.</value>
</member>
<member name="M:OxyPlot.Wpf.PlotViewBase.HideTracker">
<summary>
Hides the tracker.
</summary>
</member>
<member name="M:OxyPlot.Wpf.PlotViewBase.HideZoomRectangle">
<summary>
Hides the zoom rectangle.
</summary>
</member>
<member name="M:OxyPlot.Wpf.PlotViewBase.InvalidatePlot(System.Boolean)">
<summary>
Invalidate the PlotView (not blocking the UI thread)
</summary>
<param name="updateData">The update Data.</param>
</member>
<member name="M:OxyPlot.Wpf.PlotViewBase.OnApplyTemplate">
<inheritdoc/>
</member>
<member name="M:OxyPlot.Wpf.PlotViewBase.PanAllAxes(System.Windows.Vector)">
<summary>
Pans all axes.
</summary>
<param name="delta">The delta.</param>
</member>
<member name="M:OxyPlot.Wpf.PlotViewBase.ResetAllAxes">
<summary>
Resets all axes.
</summary>
</member>
<member name="M:OxyPlot.Wpf.PlotViewBase.SetClipboardText(System.String)">
<summary>
Stores text on the clipboard.
</summary>
<param name="text">The text.</param>
</member>
<member name="M:OxyPlot.Wpf.PlotViewBase.SetCursorType(OxyPlot.CursorType)">
<summary>
Sets the cursor type.
</summary>
<param name="cursorType">The cursor type.</param>
</member>
<member name="M:OxyPlot.Wpf.PlotViewBase.ShowTracker(OxyPlot.TrackerHitResult)">
<summary>
Shows the tracker.
</summary>
<param name="trackerHitResult">The tracker data.</param>
</member>
<member name="M:OxyPlot.Wpf.PlotViewBase.ShowZoomRectangle(OxyPlot.OxyRect)">
<summary>
Shows the zoom rectangle.
</summary>
<param name="r">The rectangle.</param>
</member>
<member name="M:OxyPlot.Wpf.PlotViewBase.ZoomAllAxes(System.Double)">
<summary>
Zooms all axes.
</summary>
<param name="factor">The zoom factor.</param>
</member>
<member name="M:OxyPlot.Wpf.PlotViewBase.ClearBackground">
<summary>
Clears the background of the plot presenter.
</summary>
</member>
<member name="M:OxyPlot.Wpf.PlotViewBase.CreatePlotPresenter">
<summary>
Creates the plot presenter.
</summary>
<returns>The plot presenter.</returns>
</member>
<member name="M:OxyPlot.Wpf.PlotViewBase.CreateRenderContext">
<summary>
Creates the render context.
</summary>
<returns>The render context.</returns>
</member>
<member name="M:OxyPlot.Wpf.PlotViewBase.OnModelChanged">
<summary>
Called when the model is changed.
</summary>
</member>
<member name="M:OxyPlot.Wpf.PlotViewBase.Render">
<summary>
Renders the plot model to the plot presenter.
</summary>
</member>
<member name="M:OxyPlot.Wpf.PlotViewBase.RenderOverride">
<summary>
Renders the plot model to the plot presenter.
</summary>
</member>
<member name="M:OxyPlot.Wpf.PlotViewBase.UpdateDpi">
<summary>
Updates the DPI scale of the render context.
</summary>
<returns>The DPI scale.</returns>
</member>
<member name="M:OxyPlot.Wpf.PlotViewBase.ModelChanged(System.Windows.DependencyObject,System.Windows.DependencyPropertyChangedEventArgs)">
<summary>
Called when the model is changed.
</summary>
<param name="d">The sender.</param>
<param name="e">The <see cref="T:System.Windows.DependencyPropertyChangedEventArgs" /> instance containing the event data.</param>
</member>
<member name="M:OxyPlot.Wpf.PlotViewBase.BeginInvoke(System.Action)">
<summary>
Invokes the specified action on the dispatcher, if necessary.
</summary>
<param name="action">The action.</param>
</member>
<member name="M:OxyPlot.Wpf.PlotViewBase.IsInVisualTree">
<summary>
Gets a value indicating whether the <see cref="T:OxyPlot.Wpf.PlotViewBase"/> is connected to the visual tree.
</summary>
<returns><c>true</c> if the PlotViewBase is connected to the visual tree; <c>false</c> otherwise.</returns>
</member>
<member name="M:OxyPlot.Wpf.PlotViewBase.OnLayoutUpdated(System.Object,System.EventArgs)">
<summary>
This event fires every time Layout updates the layout of the trees associated with current Dispatcher.
</summary>
<param name="sender">The sender.</param>
<param name="e">The event args.</param>
</member>
<member name="M:OxyPlot.Wpf.PlotViewBase.OnKeyDown(System.Windows.Input.KeyEventArgs)">
<summary>
Called before the <see cref="E:System.Windows.UIElement.KeyDown" /> event occurs.
</summary>
<param name="e">The data for the event.</param>
</member>
<member name="M:OxyPlot.Wpf.PlotViewBase.OnManipulationStarted(System.Windows.Input.ManipulationStartedEventArgs)">
<summary>
Called when the <see cref="E:System.Windows.UIElement.ManipulationStarted" /> event occurs.
</summary>
<param name="e">The data for the event.</param>
</member>
<member name="M:OxyPlot.Wpf.PlotViewBase.OnManipulationDelta(System.Windows.Input.ManipulationDeltaEventArgs)">
<summary>
Called when the <see cref="E:System.Windows.UIElement.ManipulationDelta" /> event occurs.
</summary>
<param name="e">The data for the event.</param>
</member>
<member name="M:OxyPlot.Wpf.PlotViewBase.OnManipulationCompleted(System.Windows.Input.ManipulationCompletedEventArgs)">
<summary>
Called when the <see cref="E:System.Windows.UIElement.ManipulationCompleted" /> event occurs.
</summary>
<param name="e">The data for the event.</param>
</member>
<member name="M:OxyPlot.Wpf.PlotViewBase.OnMouseWheel(System.Windows.Input.MouseWheelEventArgs)">
<summary>
Called before the <see cref="E:System.Windows.UIElement.MouseWheel" /> event occurs to provide handling for the event in a derived class without attaching a delegate.
</summary>
<param name="e">A <see cref="T:System.Windows.Input.MouseWheelEventArgs" /> that contains the event data.</param>
</member>
<member name="M:OxyPlot.Wpf.PlotViewBase.OnMouseDown(System.Windows.Input.MouseButtonEventArgs)">
<summary>
Invoked when an unhandled MouseDown attached event reaches an element in its route that is derived from this class. Implement this method to add class handling for this event.
</summary>
<param name="e">The <see cref="T:System.Windows.Input.MouseButtonEventArgs" /> that contains the event data. This event data reports details about the mouse button that was pressed and the handled state.</param>
</member>
<member name="M:OxyPlot.Wpf.PlotViewBase.OnMouseMove(System.Windows.Input.MouseEventArgs)">
<summary>
Invoked when an unhandled MouseMove attached event reaches an element in its route that is derived from this class. Implement this method to add class handling for this event.
</summary>
<param name="e">The <see cref="T:System.Windows.Input.MouseEventArgs" /> that contains the event data.</param>
</member>
<member name="M:OxyPlot.Wpf.PlotViewBase.OnMouseUp(System.Windows.Input.MouseButtonEventArgs)">
<summary>
Invoked when an unhandled MouseUp routed event reaches an element in its route that is derived from this class. Implement this method to add class handling for this event.
</summary>
<param name="e">The <see cref="T:System.Windows.Input.MouseButtonEventArgs" /> that contains the event data. The event data reports that the mouse button was released.</param>
</member>
<member name="M:OxyPlot.Wpf.PlotViewBase.OnMouseEnter(System.Windows.Input.MouseEventArgs)">
<summary>
Invoked when an unhandled <see cref="E:System.Windows.Input.Mouse.MouseEnter" /> attached event is raised on this element. Implement this method to add class handling for this event.
</summary>
<param name="e">The <see cref="T:System.Windows.Input.MouseEventArgs" /> that contains the event data.</param>
</member>
<member name="M:OxyPlot.Wpf.PlotViewBase.OnMouseLeave(System.Windows.Input.MouseEventArgs)">
<summary>
Invoked when an unhandled <see cref="E:System.Windows.Input.Mouse.MouseLeave" /> attached event is raised on this element. Implement this method to add class handling for this event.
</summary>
<param name="e">The <see cref="T:System.Windows.Input.MouseEventArgs" /> that contains the event data.</param>
</member>
<member name="F:OxyPlot.Wpf.PlotViewBase.ControllerProperty">
<summary>
Identifies the <see cref="P:OxyPlot.Wpf.PlotViewBase.Controller"/> dependency property.
</summary>
</member>
<member name="F:OxyPlot.Wpf.PlotViewBase.DefaultTrackerTemplateProperty">
<summary>
Identifies the <see cref="P:OxyPlot.Wpf.PlotViewBase.DefaultTrackerTemplate"/> dependency property.
</summary>
</member>
<member name="F:OxyPlot.Wpf.PlotViewBase.IsMouseWheelEnabledProperty">
<summary>
Identifies the <see cref="P:OxyPlot.Wpf.PlotViewBase.IsMouseWheelEnabled"/> dependency property.
</summary>
</member>
<member name="F:OxyPlot.Wpf.PlotViewBase.ModelProperty">
<summary>
Identifies the <see cref="P:OxyPlot.Wpf.PlotViewBase.Model"/> dependency property.
</summary>
</member>
<member name="F:OxyPlot.Wpf.PlotViewBase.PanCursorProperty">
<summary>
Identifies the <see cref="P:OxyPlot.Wpf.PlotViewBase.PanCursor"/> dependency property.
</summary>
</member>
<member name="F:OxyPlot.Wpf.PlotViewBase.ZoomHorizontalCursorProperty">
<summary>
Identifies the <see cref="P:OxyPlot.Wpf.PlotViewBase.ZoomHorizontalCursor"/> dependency property.
</summary>
</member>
<member name="F:OxyPlot.Wpf.PlotViewBase.ZoomRectangleCursorProperty">
<summary>
Identifies the <see cref="P:OxyPlot.Wpf.PlotViewBase.ZoomRectangleCursor"/> dependency property.
</summary>
</member>
<member name="F:OxyPlot.Wpf.PlotViewBase.ZoomRectangleTemplateProperty">
<summary>
Identifies the <see cref="P:OxyPlot.Wpf.PlotViewBase.ZoomRectangleTemplate"/> dependency property.
</summary>
</member>
<member name="F:OxyPlot.Wpf.PlotViewBase.ZoomVerticalCursorProperty">
<summary>
Identifies the <see cref="P:OxyPlot.Wpf.PlotViewBase.ZoomVerticalCursor"/> dependency property.
</summary>
</member>
<member name="P:OxyPlot.Wpf.PlotViewBase.Controller">
<summary>
Gets or sets the Plot controller.
</summary>
<value>The Plot controller.</value>
</member>
<member name="P:OxyPlot.Wpf.PlotViewBase.DefaultTrackerTemplate">
<summary>
Gets or sets the default tracker template.
</summary>
</member>
<member name="P:OxyPlot.Wpf.PlotViewBase.IsMouseWheelEnabled">
<summary>
Gets or sets a value indicating whether IsMouseWheelEnabled.
</summary>
</member>
<member name="P:OxyPlot.Wpf.PlotViewBase.Model">
<summary>
Gets or sets the model.
</summary>
<value>The model.</value>
</member>
<member name="P:OxyPlot.Wpf.PlotViewBase.PanCursor">
<summary>
Gets or sets the pan cursor.
</summary>
<value>The pan cursor.</value>
</member>
<member name="P:OxyPlot.Wpf.PlotViewBase.ZoomHorizontalCursor">
<summary>
Gets or sets the horizontal zoom cursor.
</summary>
<value>The zoom horizontal cursor.</value>
</member>
<member name="P:OxyPlot.Wpf.PlotViewBase.ZoomRectangleCursor">
<summary>
Gets or sets the rectangle zoom cursor.
</summary>
<value>The zoom rectangle cursor.</value>
</member>
<member name="P:OxyPlot.Wpf.PlotViewBase.ZoomRectangleTemplate">
<summary>
Gets or sets the zoom rectangle template.
</summary>
<value>The zoom rectangle template.</value>
</member>
<member name="P:OxyPlot.Wpf.PlotViewBase.ZoomVerticalCursor">
<summary>
Gets or sets the vertical zoom cursor.
</summary>
<value>The zoom vertical cursor.</value>
</member>
<member name="T:OxyPlot.Wpf.TrackerControl">
<summary>
The tracker control.
</summary>
</member>
<member name="F:OxyPlot.Wpf.TrackerControl.HorizontalLineVisibilityProperty">
<summary>
Identifies the <see cref="P:OxyPlot.Wpf.TrackerControl.HorizontalLineVisibility"/> dependency property.
</summary>
</member>
<member name="F:OxyPlot.Wpf.TrackerControl.VerticalLineVisibilityProperty">
<summary>
Identifies the <see cref="P:OxyPlot.Wpf.TrackerControl.VerticalLineVisibility"/> dependency property.
</summary>
</member>
<member name="F:OxyPlot.Wpf.TrackerControl.LineThicknessProperty">
<summary>
Identifies the <see cref="P:OxyPlot.Wpf.TrackerControl.LineThickness"/> dependency property.
</summary>
</member>
<member name="F:OxyPlot.Wpf.TrackerControl.LineStrokeProperty">
<summary>
Identifies the <see cref="P:OxyPlot.Wpf.TrackerControl.LineStroke"/> dependency property.
</summary>
</member>
<member name="F:OxyPlot.Wpf.TrackerControl.LineExtentsProperty">
<summary>
Identifies the <see cref="P:OxyPlot.Wpf.TrackerControl.LineExtents"/> dependency property.
</summary>
</member>
<member name="F:OxyPlot.Wpf.TrackerControl.LineDashArrayProperty">
<summary>
Identifies the <see cref="P:OxyPlot.Wpf.TrackerControl.LineDashArray"/> dependency property.
</summary>
</member>
<member name="F:OxyPlot.Wpf.TrackerControl.BorderEdgeModeProperty">
<summary>
Identifies the <see cref="P:OxyPlot.Wpf.TrackerControl.BorderEdgeMode"/> dependency property.
</summary>
</member>
<member name="F:OxyPlot.Wpf.TrackerControl.ShowPointerProperty">
<summary>
Identifies the <see cref="P:OxyPlot.Wpf.TrackerControl.ShowPointer"/> dependency property.
</summary>
</member>
<member name="F:OxyPlot.Wpf.TrackerControl.CornerRadiusProperty">
<summary>
Identifies the <see cref="P:OxyPlot.Wpf.TrackerControl.CornerRadius"/> dependency property.
</summary>
</member>
<member name="F:OxyPlot.Wpf.TrackerControl.DistanceProperty">
<summary>
Identifies the <see cref="P:OxyPlot.Wpf.TrackerControl.Distance"/> dependency property.
</summary>
</member>
<member name="F:OxyPlot.Wpf.TrackerControl.CanCenterHorizontallyProperty">
<summary>
Identifies the <see cref="P:OxyPlot.Wpf.TrackerControl.CanCenterHorizontally"/> dependency property.
</summary>
</member>
<member name="F:OxyPlot.Wpf.TrackerControl.CanCenterVerticallyProperty">
<summary>
Identifies the <see cref="P:OxyPlot.Wpf.TrackerControl.CanCenterVertically"/> dependency property.
</summary>
</member>
<member name="F:OxyPlot.Wpf.TrackerControl.PositionProperty">
<summary>
Identifies the <see cref="P:OxyPlot.Wpf.TrackerControl.Position"/> dependency property.
</summary>
</member>
<member name="F:OxyPlot.Wpf.TrackerControl.PartPath">
<summary>
The path part string.
</summary>
</member>
<member name="F:OxyPlot.Wpf.TrackerControl.PartContent">
<summary>
The content part string.
</summary>
</member>
<member name="F:OxyPlot.Wpf.TrackerControl.PartContentcontainer">
<summary>
The content container part string.
</summary>
</member>
<member name="F:OxyPlot.Wpf.TrackerControl.PartHorizontalline">
<summary>
The horizontal line part string.
</summary>
</member>
<member name="F:OxyPlot.Wpf.TrackerControl.PartVerticalline">
<summary>
The vertical line part string.
</summary>
</member>
<member name="F:OxyPlot.Wpf.TrackerControl.content">
<summary>
The content.
</summary>
</member>
<member name="F:OxyPlot.Wpf.TrackerControl.horizontalLine">
<summary>
The horizontal line.
</summary>
</member>
<member name="F:OxyPlot.Wpf.TrackerControl.path">
<summary>
The path.
</summary>
</member>
<member name="F:OxyPlot.Wpf.TrackerControl.contentContainer">
<summary>
The content container.
</summary>
</member>
<member name="F:OxyPlot.Wpf.TrackerControl.verticalLine">
<summary>
The vertical line.
</summary>
</member>
<member name="M:OxyPlot.Wpf.TrackerControl.#cctor">
<summary>
Initializes static members of the <see cref = "T:OxyPlot.Wpf.TrackerControl" /> class.
</summary>
</member>
<member name="P:OxyPlot.Wpf.TrackerControl.BorderEdgeMode">
<summary>
Gets or sets BorderEdgeMode.
</summary>
</member>
<member name="P:OxyPlot.Wpf.TrackerControl.HorizontalLineVisibility">
<summary>
Gets or sets HorizontalLineVisibility.
</summary>
</member>
<member name="P:OxyPlot.Wpf.TrackerControl.VerticalLineVisibility">
<summary>
Gets or sets VerticalLineVisibility.
</summary>
</member>
<member name="P:OxyPlot.Wpf.TrackerControl.LineThickness">
<summary>
Gets or sets LineThickness.
</summary>
</member>
<member name="P:OxyPlot.Wpf.TrackerControl.LineStroke">
<summary>
Gets or sets LineStroke.
</summary>
</member>
<member name="P:OxyPlot.Wpf.TrackerControl.LineExtents">
<summary>
Gets or sets LineExtents.
</summary>
</member>
<member name="P:OxyPlot.Wpf.TrackerControl.LineDashArray">
<summary>
Gets or sets LineDashArray.
</summary>
</member>
<member name="P:OxyPlot.Wpf.TrackerControl.ShowPointer">
<summary>
Gets or sets a value indicating whether to show a 'pointer' on the border.
</summary>
</member>
<member name="P:OxyPlot.Wpf.TrackerControl.CornerRadius">
<summary>
Gets or sets the corner radius (only used when ShowPoint=<c>false</c>).
</summary>
</member>
<member name="P:OxyPlot.Wpf.TrackerControl.Distance">
<summary>
Gets or sets the distance of the content container from the trackers Position.
</summary>
</member>
<member name="P:OxyPlot.Wpf.TrackerControl.CanCenterHorizontally">
<summary>
Gets or sets a value indicating whether the tracker can center its content box horizontally.
</summary>
</member>
<member name="P:OxyPlot.Wpf.TrackerControl.CanCenterVertically">
<summary>
Gets or sets a value indicating whether the tracker can center its content box vertically.
</summary>
</member>
<member name="P:OxyPlot.Wpf.TrackerControl.Position">
<summary>
Gets or sets Position of the tracker.
</summary>
</member>
<member name="M:OxyPlot.Wpf.TrackerControl.OnApplyTemplate">
<summary>
When overridden in a derived class, is invoked whenever application code or internal processes call <see cref="M:System.Windows.FrameworkElement.ApplyTemplate" />.
</summary>
</member>
<member name="M:OxyPlot.Wpf.TrackerControl.PositionChanged(System.Windows.DependencyObject,System.Windows.DependencyPropertyChangedEventArgs)">
<summary>
Called when the position is changed.
</summary>
<param name="sender">The sender.</param>
<param name="e">The <see cref="T:System.Windows.DependencyPropertyChangedEventArgs" /> instance containing the event data.</param>
</member>
<member name="M:OxyPlot.Wpf.TrackerControl.OnPositionChanged(System.Windows.DependencyPropertyChangedEventArgs)">
<summary>
Called when the position is changed.
</summary>
<param name="dependencyPropertyChangedEventArgs">The dependency property changed event args.</param>
</member>
<member name="M:OxyPlot.Wpf.TrackerControl.UpdatePositionAndBorder">
<summary>
Update the position and border of the tracker.
</summary>
</member>
<member name="M:OxyPlot.Wpf.TrackerControl.CreateBorderGeometry(System.Windows.HorizontalAlignment,System.Windows.VerticalAlignment,System.Double,System.Double,System.Windows.Thickness@)">
<summary>
Create the border geometry.
</summary>
<param name="ha">The horizontal alignment.</param>
<param name="va">The vertical alignment.</param>
<param name="width">The width.</param>
<param name="height">The height.</param>
<param name="margin">The margin.</param>
<returns>The border geometry.</returns>
</member>
<member name="M:OxyPlot.Wpf.TrackerControl.CreatePointerBorderGeometry(System.Windows.HorizontalAlignment,System.Windows.VerticalAlignment,System.Double,System.Double,System.Windows.Thickness@)">
<summary>
Create a border geometry with a 'pointer'.
</summary>
<param name="ha">The horizontal alignment.</param>
<param name="va">The vertical alignment.</param>
<param name="width">The width.</param>
<param name="height">The height.</param>
<param name="margin">The margin.</param>
<returns>The border geometry.</returns>
</member>
<member name="T:OxyPlot.Wpf.TrackerDefinition">
<summary>
Represents a tracker definition.
</summary>
<remarks>The tracker definitions make it possible to show different trackers for different series.
The <see cref="P:OxyPlot.Series.Series.TrackerKey" /> property is matched with the <see cref="P:OxyPlot.Wpf.TrackerDefinition.TrackerKey" />
in the TrackerDefinitions collection in the <see cref="T:OxyPlot.Wpf.PlotViewBase" /> control.</remarks>
</member>
<member name="F:OxyPlot.Wpf.TrackerDefinition.TrackerKeyProperty">
<summary>
Identifies the <see cref="P:OxyPlot.Wpf.TrackerDefinition.TrackerKey"/> dependency property.
</summary>
</member>
<member name="F:OxyPlot.Wpf.TrackerDefinition.TrackerTemplateProperty">
<summary>
Identifies the <see cref="P:OxyPlot.Wpf.TrackerDefinition.TrackerTemplate"/> dependency property.
</summary>
</member>
<member name="P:OxyPlot.Wpf.TrackerDefinition.TrackerKey">
<summary>
Gets or sets the tracker key.
</summary>
<remarks>The Plot will use this property to find the TrackerDefinition that matches the TrackerKey of the current series.</remarks>
</member>
<member name="P:OxyPlot.Wpf.TrackerDefinition.TrackerTemplate">
<summary>
Gets or sets the tracker template.
</summary>
<remarks>The tracker control will be added/removed from the Tracker overlay as necessary.
The DataContext of the tracker will be set to a TrackerHitResult with the current tracker data.</remarks>
</member>
<member name="T:OxyPlot.Wpf.ConverterExtensions">
<summary>
Extension method used to convert to/from Windows/Windows.Media classes.
</summary>
</member>
<member name="M:OxyPlot.Wpf.ConverterExtensions.DistanceTo(System.Windows.Point,System.Windows.Point)">
<summary>
Calculate the distance between two points.
</summary>
<param name="p1">The first point.</param>
<param name="p2">The second point.</param>
<returns>The distance.</returns>
</member>
<member name="M:OxyPlot.Wpf.ConverterExtensions.ToBrush(OxyPlot.OxyColor)">
<summary>
Converts an <see cref="T:OxyPlot.OxyColor" /> to a <see cref="T:System.Windows.Media.Brush" />.
</summary>
<param name="c">The color.</param>
<returns>A <see cref="T:System.Windows.Media.SolidColorBrush" />.</returns>
</member>
<member name="M:OxyPlot.Wpf.ConverterExtensions.ToColor(OxyPlot.OxyColor)">
<summary>
Converts an <see cref="T:OxyPlot.OxyColor" /> to a <see cref="T:System.Windows.Media.Color" />.
</summary>
<param name="c">The color.</param>
<returns>A Color.</returns>
</member>
<member name="M:OxyPlot.Wpf.ConverterExtensions.ToThickness(OxyPlot.OxyThickness)">
<summary>
Converts an OxyThickness to a Thickness.
</summary>
<param name="c">The thickness.</param>
<returns>A <see cref="T:System.Windows.Thickness" /> instance.</returns>
</member>
<member name="M:OxyPlot.Wpf.ConverterExtensions.ToVector(OxyPlot.ScreenVector)">
<summary>
Converts a ScreenVector to a Vector.
</summary>
<param name="c">The c.</param>
<returns>A <see cref="T:System.Windows.Vector" /> instance.</returns>
</member>
<member name="M:OxyPlot.Wpf.ConverterExtensions.ToHorizontalAlignment(System.Windows.HorizontalAlignment)">
<summary>
Converts a HorizontalAlignment to a HorizontalAlignment.
</summary>
<param name="alignment">The alignment.</param>
<returns>A HorizontalAlignment.</returns>
</member>
<member name="M:OxyPlot.Wpf.ConverterExtensions.ToVerticalAlignment(System.Windows.VerticalAlignment)">
<summary>
Converts a HorizontalAlignment to a VerticalAlignment.
</summary>
<param name="alignment">The alignment.</param>
<returns>A VerticalAlignment.</returns>
</member>
<member name="M:OxyPlot.Wpf.ConverterExtensions.ToOxyColor(System.Windows.Media.Color)">
<summary>
Converts a Color to an OxyColor.
</summary>
<param name="color">The color.</param>
<returns>An OxyColor.</returns>
</member>
<member name="M:OxyPlot.Wpf.ConverterExtensions.ToOxyColor(System.Windows.Media.Brush)">
<summary>
Converts a <see cref="T:System.Windows.Media.Brush" /> to an <see cref="T:OxyPlot.OxyColor" />.
</summary>
<param name="brush">The brush.</param>
<returns>An <see cref="T:OxyPlot.OxyColor" />.</returns>
</member>
<member name="M:OxyPlot.Wpf.ConverterExtensions.ToOxyThickness(System.Windows.Thickness)">
<summary>
Converts a Thickness to an <see cref="T:OxyPlot.OxyThickness" />.
</summary>
<param name="t">The thickness.</param>
<returns>An <see cref="T:OxyPlot.OxyThickness" />.</returns>
</member>
<member name="M:OxyPlot.Wpf.ConverterExtensions.ToScreenPoint(System.Windows.Point)">
<summary>
Converts a <see cref="T:System.Windows.Point" /> to a <see cref="T:OxyPlot.ScreenPoint" />.
</summary>
<param name="pt">The point.</param>
<returns>A <see cref="T:OxyPlot.ScreenPoint" />.</returns>
</member>
<member name="M:OxyPlot.Wpf.ConverterExtensions.ToScreenPointArray(System.Windows.Point[])">
<summary>
Converts a Point array to a ScreenPoint array.
</summary>
<param name="points">The points.</param>
<returns>A ScreenPoint array.</returns>
</member>
<member name="M:OxyPlot.Wpf.ConverterExtensions.ToScreenVector(System.Windows.Vector)">
<summary>
Converts the specified vector to a ScreenVector.
</summary>
<param name="vector">The vector.</param>
<returns>A <see cref="T:OxyPlot.ScreenVector" />.</returns>
</member>
<member name="M:OxyPlot.Wpf.ConverterExtensions.Convert(System.Windows.Input.Key)">
<summary>
Converts the specified key.
</summary>
<param name="k">The key to convert.</param>
<returns>The converted key.</returns>
</member>
<member name="M:OxyPlot.Wpf.ConverterExtensions.Convert(System.Windows.Input.MouseButton)">
<summary>
Converts the specified button.
</summary>
<param name="button">The button to convert.</param>
<returns>The converted mouse button.</returns>
</member>
<member name="M:OxyPlot.Wpf.ConverterExtensions.ToMouseWheelEventArgs(System.Windows.Input.MouseWheelEventArgs,System.Windows.IInputElement)">
<summary>
Converts <see cref="T:System.Windows.Input.MouseWheelEventArgs" /> to <see cref="T:OxyPlot.OxyMouseWheelEventArgs" /> for a mouse wheel event.
</summary>
<param name="e">The <see cref="T:System.Windows.Input.MouseWheelEventArgs" /> instance containing the event data.</param>
<param name="relativeTo">The <see cref="T:System.Windows.IInputElement" /> that the event is relative to.</param>
<returns>A <see cref="T:OxyPlot.OxyMouseWheelEventArgs" /> containing the converted event arguments.</returns>
</member>
<member name="M:OxyPlot.Wpf.ConverterExtensions.ToMouseDownEventArgs(System.Windows.Input.MouseButtonEventArgs,System.Windows.IInputElement)">
<summary>
Converts <see cref="T:System.Windows.Input.MouseButtonEventArgs" /> to <see cref="T:OxyPlot.OxyMouseEventArgs" /> for a mouse down event.
</summary>
<param name="e">The <see cref="T:System.Windows.Input.MouseButtonEventArgs" /> instance containing the event data.</param>
<param name="relativeTo">The <see cref="T:System.Windows.IInputElement" /> that the event is relative to.</param>
<returns>A <see cref="T:OxyPlot.OxyMouseEventArgs" /> containing the converted event arguments.</returns>
</member>
<member name="M:OxyPlot.Wpf.ConverterExtensions.ToMouseReleasedEventArgs(System.Windows.Input.MouseButtonEventArgs,System.Windows.IInputElement)">
<summary>
Converts <see cref="T:System.Windows.Input.MouseButtonEventArgs" /> to <see cref="T:OxyPlot.OxyMouseEventArgs" /> for a mouse up event.
</summary>
<param name="e">The <see cref="T:System.Windows.Input.MouseButtonEventArgs" /> instance containing the event data.</param>
<param name="relativeTo">The <see cref="T:System.Windows.IInputElement" /> that the event is relative to.</param>
<returns>A <see cref="T:OxyPlot.OxyMouseEventArgs" /> containing the converted event arguments.</returns>
</member>
<member name="M:OxyPlot.Wpf.ConverterExtensions.ToMouseEventArgs(System.Windows.Input.MouseEventArgs,System.Windows.IInputElement)">
<summary>
Converts <see cref="T:System.Windows.Input.MouseEventArgs" /> to <see cref="T:OxyPlot.OxyMouseEventArgs" /> for a mouse event.
</summary>
<param name="e">The <see cref="T:System.Windows.Input.MouseEventArgs" /> instance containing the event data.</param>
<param name="relativeTo">The <see cref="T:System.Windows.IInputElement" /> that the event is relative to.</param>
<returns>A <see cref="T:OxyPlot.OxyMouseEventArgs" /> containing the converted event arguments.</returns>
</member>
<member name="M:OxyPlot.Wpf.ConverterExtensions.ToTouchEventArgs(System.Windows.Input.ManipulationStartedEventArgs,System.Windows.UIElement)">
<summary>
Converts <see cref="T:System.Windows.Input.ManipulationStartedEventArgs" /> to <see cref="T:OxyPlot.OxyMouseEventArgs" /> for a touch started event.
</summary>
<param name="e">The <see cref="T:System.Windows.Input.ManipulationStartedEventArgs" /> instance containing the event data.</param>
<param name="relativeTo">The <see cref="T:System.Windows.UIElement" /> that the event is relative to.</param>
<returns>A <see cref="T:OxyPlot.OxyMouseEventArgs" /> containing the converted event arguments.</returns>
</member>
<member name="M:OxyPlot.Wpf.ConverterExtensions.ToTouchEventArgs(System.Windows.Input.ManipulationDeltaEventArgs,System.Windows.UIElement)">
<summary>
Converts <see cref="T:System.Windows.Input.ManipulationDeltaEventArgs" /> to <see cref="T:OxyPlot.OxyMouseEventArgs" /> for a touch delta event.
</summary>
<param name="e">The <see cref="T:System.Windows.Input.ManipulationDeltaEventArgs" /> instance containing the event data.</param>
<param name="relativeTo">The <see cref="T:System.Windows.UIElement" /> that the event is relative to.</param>
<returns>A <see cref="T:OxyPlot.OxyMouseEventArgs" /> containing the converted event arguments.</returns>
</member>
<member name="M:OxyPlot.Wpf.ConverterExtensions.ToTouchEventArgs(System.Windows.Input.ManipulationCompletedEventArgs,System.Windows.UIElement)">
<summary>
Converts <see cref="T:System.Windows.Input.ManipulationCompletedEventArgs" /> to <see cref="T:OxyPlot.OxyMouseEventArgs" /> for a touch completed event.
</summary>
<param name="e">The <see cref="T:System.Windows.Input.ManipulationCompletedEventArgs" /> instance containing the event data.</param>
<param name="relativeTo">The <see cref="T:System.Windows.UIElement" /> that the event is relative to.</param>
<returns>A <see cref="T:OxyPlot.OxyMouseEventArgs" /> containing the converted event arguments.</returns>
</member>
<member name="T:OxyPlot.Wpf.Keyboard">
<summary>
Provides utility methods related to the keyboard.
</summary>
</member>
<member name="M:OxyPlot.Wpf.Keyboard.GetModifierKeys">
<summary>
Gets the current modifier keys.
</summary>
<returns>A <see cref="T:OxyPlot.OxyModifierKeys" /> value.</returns>
</member>
</members>
</doc>

@ -1,637 +0,0 @@
<?xml version="1.0"?>
<doc>
<assembly>
<name>OxyPlot.Wpf</name>
</assembly>
<members>
<member name="T:OxyPlot.Wpf.CanvasRenderContext">
<summary>
Implements <see cref="T:OxyPlot.IRenderContext" /> for <see cref="T:System.Windows.Controls.Canvas" />.
</summary>
</member>
<member name="F:OxyPlot.Wpf.CanvasRenderContext.imagesInUse">
<summary>
The images in use
</summary>
</member>
<member name="F:OxyPlot.Wpf.CanvasRenderContext.imageCache">
<summary>
The image cache
</summary>
</member>
<member name="F:OxyPlot.Wpf.CanvasRenderContext.brushCache">
<summary>
The brush cache.
</summary>
</member>
<member name="F:OxyPlot.Wpf.CanvasRenderContext.fontFamilyCache">
<summary>
The font family cache
</summary>
</member>
<member name="F:OxyPlot.Wpf.CanvasRenderContext.canvas">
<summary>
The canvas.
</summary>
</member>
<member name="F:OxyPlot.Wpf.CanvasRenderContext.clip">
<summary>
The clip rectangle.
</summary>
</member>
<member name="F:OxyPlot.Wpf.CanvasRenderContext.currentToolTip">
<summary>
The current tool tip
</summary>
</member>
<member name="P:OxyPlot.Wpf.CanvasRenderContext.DpiScale">
<summary>
The dpi scale.
</summary>
</member>
<member name="P:OxyPlot.Wpf.CanvasRenderContext.VisualOffset">
<summary>
The visual offset relative to visual root.
</summary>
</member>
<member name="M:OxyPlot.Wpf.CanvasRenderContext.#ctor(System.Windows.Controls.Canvas)">
<summary>
Initializes a new instance of the <see cref="T:OxyPlot.Wpf.CanvasRenderContext" /> class.
</summary>
<param name="canvas">The canvas.</param>
</member>
<member name="P:OxyPlot.Wpf.CanvasRenderContext.TextMeasurementMethod">
<summary>
Gets or sets the text measurement method.
</summary>
<value>The text measurement method.</value>
</member>
<member name="P:OxyPlot.Wpf.CanvasRenderContext.TextFormattingMode">
<summary>
Gets or sets the text formatting mode.
</summary>
<value>The text formatting mode. The default value is <see cref="F:System.Windows.Media.TextFormattingMode.Display"/>.</value>
</member>
<member name="M:OxyPlot.Wpf.CanvasRenderContext.DrawEllipse(OxyPlot.OxyRect,OxyPlot.OxyColor,OxyPlot.OxyColor,System.Double,OxyPlot.EdgeRenderingMode)">
<inheritdoc/>
</member>
<member name="M:OxyPlot.Wpf.CanvasRenderContext.DrawEllipses(System.Collections.Generic.IList{OxyPlot.OxyRect},OxyPlot.OxyColor,OxyPlot.OxyColor,System.Double,OxyPlot.EdgeRenderingMode)">
<inheritdoc/>
</member>
<member name="M:OxyPlot.Wpf.CanvasRenderContext.DrawLine(System.Collections.Generic.IList{OxyPlot.ScreenPoint},OxyPlot.OxyColor,System.Double,OxyPlot.EdgeRenderingMode,System.Double[],OxyPlot.LineJoin)">
<inheritdoc/>
</member>
<member name="M:OxyPlot.Wpf.CanvasRenderContext.DrawLineSegments(System.Collections.Generic.IList{OxyPlot.ScreenPoint},OxyPlot.OxyColor,System.Double,OxyPlot.EdgeRenderingMode,System.Double[],OxyPlot.LineJoin)">
<inheritdoc/>
</member>
<member name="M:OxyPlot.Wpf.CanvasRenderContext.DrawPolygon(System.Collections.Generic.IList{OxyPlot.ScreenPoint},OxyPlot.OxyColor,OxyPlot.OxyColor,System.Double,OxyPlot.EdgeRenderingMode,System.Double[],OxyPlot.LineJoin)">
<inheritdoc/>
</member>
<member name="M:OxyPlot.Wpf.CanvasRenderContext.DrawPolygons(System.Collections.Generic.IList{System.Collections.Generic.IList{OxyPlot.ScreenPoint}},OxyPlot.OxyColor,OxyPlot.OxyColor,System.Double,OxyPlot.EdgeRenderingMode,System.Double[],OxyPlot.LineJoin)">
<inheritdoc/>
</member>
<member name="M:OxyPlot.Wpf.CanvasRenderContext.DrawRectangle(OxyPlot.OxyRect,OxyPlot.OxyColor,OxyPlot.OxyColor,System.Double,OxyPlot.EdgeRenderingMode)">
<inheritdoc/>
</member>
<member name="M:OxyPlot.Wpf.CanvasRenderContext.DrawRectangles(System.Collections.Generic.IList{OxyPlot.OxyRect},OxyPlot.OxyColor,OxyPlot.OxyColor,System.Double,OxyPlot.EdgeRenderingMode)">
<inheritdoc/>
</member>
<member name="M:OxyPlot.Wpf.CanvasRenderContext.DrawText(OxyPlot.ScreenPoint,System.String,OxyPlot.OxyColor,System.String,System.Double,System.Double,System.Double,OxyPlot.HorizontalAlignment,OxyPlot.VerticalAlignment,System.Nullable{OxyPlot.OxySize})">
<inheritdoc/>
</member>
<member name="M:OxyPlot.Wpf.CanvasRenderContext.MeasureText(System.String,System.String,System.Double,System.Double)">
<inheritdoc/>
</member>
<member name="M:OxyPlot.Wpf.CanvasRenderContext.SetToolTip(System.String)">
<inheritdoc/>
</member>
<member name="M:OxyPlot.Wpf.CanvasRenderContext.DrawImage(OxyPlot.OxyImage,System.Double,System.Double,System.Double,System.Double,System.Double,System.Double,System.Double,System.Double,System.Double,System.Boolean)">
<inheritdoc/>
</member>
<member name="M:OxyPlot.Wpf.CanvasRenderContext.SetClip(OxyPlot.OxyRect)">
<inheritdoc/>
</member>
<member name="M:OxyPlot.Wpf.CanvasRenderContext.ResetClip">
<inheritdoc/>
</member>
<member name="M:OxyPlot.Wpf.CanvasRenderContext.CleanUp">
<inheritdoc/>
</member>
<member name="M:OxyPlot.Wpf.CanvasRenderContext.MeasureTextByGlyphTypeface(System.String,System.String,System.Double,System.Double)">
<summary>
Measures the size of the specified text by a faster method (using GlyphTypefaces).
</summary>
<param name="text">The text.</param>
<param name="fontFamily">The font family.</param>
<param name="fontSize">The font size.</param>
<param name="fontWeight">The font weight.</param>
<returns>The size of the text.</returns>
</member>
<member name="M:OxyPlot.Wpf.CanvasRenderContext.GetFontWeight(System.Double)">
<summary>
Gets the font weight.
</summary>
<param name="fontWeight">The font weight value.</param>
<returns>The font weight.</returns>
</member>
<member name="M:OxyPlot.Wpf.CanvasRenderContext.MeasureTextSize(System.Windows.Media.GlyphTypeface,System.Double,System.String)">
<summary>
Fast text size calculation
</summary>
<param name="glyphTypeface">The glyph typeface.</param>
<param name="sizeInEm">The size.</param>
<param name="s">The text.</param>
<returns>The text size.</returns>
</member>
<member name="M:OxyPlot.Wpf.CanvasRenderContext.CreateAndAdd``1(System.Double,System.Double)">
<summary>
Creates an element of the specified type and adds it to the canvas.
</summary>
<typeparam name="T">Type of element to create.</typeparam>
<param name="clipOffsetX">The clip offset executable.</param>
<param name="clipOffsetY">The clip offset asynchronous.</param>
<returns>The element.</returns>
</member>
<member name="M:OxyPlot.Wpf.CanvasRenderContext.ApplyToolTip(System.Windows.FrameworkElement)">
<summary>
Applies the current tool tip to the specified element.
</summary>
<param name="element">The element.</param>
</member>
<member name="M:OxyPlot.Wpf.CanvasRenderContext.GetCachedBrush(OxyPlot.OxyColor)">
<summary>
Gets the cached brush.
</summary>
<param name="color">The color.</param>
<returns>The brush.</returns>
</member>
<member name="M:OxyPlot.Wpf.CanvasRenderContext.GetCachedFontFamily(System.String)">
<summary>
Gets the cached font family.
</summary>
<param name="familyName">Name of the family.</param>
<returns>The FontFamily.</returns>
</member>
<member name="M:OxyPlot.Wpf.CanvasRenderContext.SetStroke(System.Windows.Shapes.Shape,OxyPlot.OxyColor,System.Double,OxyPlot.EdgeRenderingMode,OxyPlot.LineJoin,System.Collections.Generic.IEnumerable{System.Double},System.Double)">
<summary>
Sets the stroke properties of the specified shape object.
</summary>
<param name="shape">The shape.</param>
<param name="stroke">The stroke color.</param>
<param name="thickness">The thickness.</param>
<param name="edgeRenderingMode">The edge rendering mode.</param>
<param name="lineJoin">The line join.</param>
<param name="dashArray">The dash array. Use <c>null</c> to get a solid line.</param>
<param name="dashOffset">The dash offset.</param>
</member>
<member name="M:OxyPlot.Wpf.CanvasRenderContext.GetImageSource(OxyPlot.OxyImage)">
<summary>
Gets the bitmap source.
</summary>
<param name="image">The image.</param>
<returns>The bitmap source.</returns>
</member>
<member name="M:OxyPlot.Wpf.CanvasRenderContext.ToRect(OxyPlot.OxyRect)">
<summary>
Converts an <see cref="T:OxyPlot.OxyRect" /> to a <see cref="T:System.Windows.Rect" />.
</summary>
<param name="r">The rectangle.</param>
<returns>A <see cref="T:System.Windows.Rect" />.</returns>
</member>
<member name="M:OxyPlot.Wpf.CanvasRenderContext.GetActualPoints(System.Collections.Generic.IList{OxyPlot.ScreenPoint},System.Double,OxyPlot.EdgeRenderingMode)">
<summary>
Snaps points to pixels if required by the edge rendering mode.
</summary>
<param name="points">The points.</param>
<param name="strokeThickness">The stroke thickness.</param>
<param name="edgeRenderingMode">The edge rendering mode.</param>
<returns>The processed points.</returns>
</member>
<member name="M:OxyPlot.Wpf.CanvasRenderContext.GetActualRect(OxyPlot.OxyRect,System.Double,OxyPlot.EdgeRenderingMode)">
<summary>
Snaps a rectangle to device pixels if required by the edge rendering mode.
</summary>
<param name="rect">The rectangle.</param>
<param name="strokeThickness">The stroke thickness.</param>
<param name="edgeRenderingMode">The edge rendering mode.</param>
<returns>The processed rectangle.</returns>
</member>
<member name="M:OxyPlot.Wpf.CanvasRenderContext.GetActualStrokeThickness(System.Double,OxyPlot.EdgeRenderingMode)">
<summary>
Snaps a stroke thickness to device pixels if required by the edge rendering mode.
</summary>
<param name="strokeThickness">The stroke thickness.</param>
<param name="edgeRenderingMode">The edge rendering mode.</param>
<returns>The processed stroke thickness.</returns>
</member>
<member name="T:OxyPlot.Wpf.PlotView">
<summary>
Represents a control that displays a <see cref="T:OxyPlot.PlotModel" />. This <see cref="T:OxyPlot.IPlotView"/> is based on <see cref="T:OxyPlot.Wpf.CanvasRenderContext"/>.
</summary>
<summary>
Represents a control that displays a <see cref="T:OxyPlot.PlotModel" />.
</summary>
</member>
<member name="F:OxyPlot.Wpf.PlotView.TextMeasurementMethodProperty">
<summary>
Identifies the <see cref="P:OxyPlot.Wpf.PlotView.TextMeasurementMethod"/> dependency property.
</summary>
</member>
<member name="M:OxyPlot.Wpf.PlotView.#ctor">
<summary>
Initializes a new instance of the <see cref="T:OxyPlot.Wpf.PlotView" /> class.
</summary>
</member>
<member name="P:OxyPlot.Wpf.PlotView.DisconnectCanvasWhileUpdating">
<summary>
Gets or sets a value indicating whether to disconnect the canvas while updating.
</summary>
<value><c>true</c> if canvas should be disconnected while updating; otherwise, <c>false</c>.</value>
</member>
<member name="P:OxyPlot.Wpf.PlotView.TextMeasurementMethod">
<summary>
Gets or sets the vertical zoom cursor.
</summary>
<value>The zoom vertical cursor.</value>
</member>
<member name="P:OxyPlot.Wpf.PlotView.Canvas">
<summary>
Gets the Canvas.
</summary>
</member>
<member name="P:OxyPlot.Wpf.PlotView.RenderContext">
<summary>
Gets the CanvasRenderContext.
</summary>
</member>
<member name="M:OxyPlot.Wpf.PlotView.ClearBackground">
<inheritdoc/>
</member>
<member name="M:OxyPlot.Wpf.PlotView.CreatePlotPresenter">
<inheritdoc/>
</member>
<member name="M:OxyPlot.Wpf.PlotView.CreateRenderContext">
<inheritdoc/>
</member>
<member name="M:OxyPlot.Wpf.PlotView.OnRender(System.Windows.Media.DrawingContext)">
<inheritdoc/>
</member>
<member name="M:OxyPlot.Wpf.PlotView.RenderOverride">
<inheritdoc/>
</member>
<member name="M:OxyPlot.Wpf.PlotView.UpdateDpi">
<inheritdoc/>
</member>
<member name="M:OxyPlot.Wpf.PlotView.DoCopy(System.Object,System.Windows.Input.ExecutedRoutedEventArgs)">
<summary>
Performs the copy operation.
</summary>
<param name="sender">The sender.</param>
<param name="e">The <see cref="T:System.Windows.Input.ExecutedRoutedEventArgs" /> instance containing the event data.</param>
</member>
<member name="M:OxyPlot.Wpf.PlotView.GetAncestorVisualFromVisualTree(System.Windows.DependencyObject)">
<summary>
Returns a reference to the visual object that hosts the dependency object in the visual tree.
</summary>
<returns> The host window from the visual tree.</returns>
</member>
<member name="M:OxyPlot.Wpf.PlotView.SaveBitmap(System.String)">
<summary>
Saves the PlotView as a bitmap.
</summary>
<param name="fileName">Name of the file.</param>
</member>
<member name="M:OxyPlot.Wpf.PlotView.SaveBitmap(System.String,System.Int32,System.Int32)">
<summary>
Saves the PlotView as a bitmap.
</summary>
<param name="fileName">Name of the file.</param>
<param name="width">The width.</param>
<param name="height">The height.</param>
</member>
<member name="M:OxyPlot.Wpf.PlotView.SaveXaml(System.String)">
<summary>
Saves the PlotView as xaml.
</summary>
<param name="fileName">Name of the file.</param>
</member>
<member name="M:OxyPlot.Wpf.PlotView.ToXaml">
<summary>
Renders the PlotView to xaml.
</summary>
<returns>The xaml.</returns>
</member>
<member name="M:OxyPlot.Wpf.PlotView.ToBitmap">
<summary>
Renders the PlotView to a bitmap.
</summary>
<returns>A bitmap.</returns>
</member>
<member name="T:OxyPlot.Wpf.PngExporter">
<summary>
Provides functionality to export plots to png.
</summary>
</member>
<member name="M:OxyPlot.Wpf.PngExporter.#ctor">
<summary>
Initializes a new instance of the <see cref="T:OxyPlot.Wpf.PngExporter" /> class.
</summary>
</member>
<member name="P:OxyPlot.Wpf.PngExporter.Width">
<summary>
Gets or sets the width of the output image.
</summary>
</member>
<member name="P:OxyPlot.Wpf.PngExporter.Height">
<summary>
Gets or sets the height of the output image.
</summary>
</member>
<member name="P:OxyPlot.Wpf.PngExporter.Resolution">
<summary>
Gets or sets the resolution of the output image.
</summary>
<value>The resolution in dots per inch (dpi).</value>
</member>
<member name="M:OxyPlot.Wpf.PngExporter.Export(OxyPlot.IPlotModel,System.String,System.Int32,System.Int32,System.Double)">
<summary>
Exports the specified plot model to a file.
</summary>
<param name="model">The model to export.</param>
<param name="fileName">The file name.</param>
<param name="width">The width of the output bitmap.</param>
<param name="height">The height of the output bitmap.</param>
<param name="resolution">The resolution (resolution). The default value is 96.</param>
</member>
<member name="M:OxyPlot.Wpf.PngExporter.Export(OxyPlot.IPlotModel,System.IO.Stream)">
<summary>
Exports the specified <see cref="T:OxyPlot.PlotModel" /> to the specified <see cref="T:System.IO.Stream" />.
</summary>
<param name="model">The model.</param>
<param name="stream">The output stream.</param>
</member>
<member name="M:OxyPlot.Wpf.PngExporter.ExportToBitmap(OxyPlot.IPlotModel)">
<summary>
Exports the specified plot model to a bitmap.
</summary>
<param name="model">The model to export.</param>
<returns>A bitmap.</returns>
</member>
<member name="T:OxyPlot.Wpf.SvgExporter">
<summary>
Provides functionality to export plots to scalable vector graphics using text measuring in WPF.
</summary>
</member>
<member name="M:OxyPlot.Wpf.SvgExporter.#ctor">
<summary>
Initializes a new instance of the <see cref="T:OxyPlot.Wpf.SvgExporter" /> class.
</summary>
</member>
<member name="T:OxyPlot.Wpf.TextMeasurementMethod">
<summary>
The text measurement methods.
</summary>
</member>
<member name="F:OxyPlot.Wpf.TextMeasurementMethod.TextBlock">
<summary>
Measurement by TextBlock. This gives a more accurate result than <see cref="F:OxyPlot.Wpf.TextMeasurementMethod.GlyphTypeface"/> as it takes into account text shaping.
</summary>
</member>
<member name="F:OxyPlot.Wpf.TextMeasurementMethod.GlyphTypeface">
<summary>
Measurement by glyph typeface. This is faster than <see cref="F:OxyPlot.Wpf.TextMeasurementMethod.TextBlock"/>, but does not take into account text shaping.
</summary>
</member>
<member name="T:OxyPlot.Wpf.PixelLayout">
<summary>
Provides functionality to support non-default dpi scaling
</summary>
</member>
<member name="M:OxyPlot.Wpf.PixelLayout.Snap(System.Double,System.Double,System.Double,System.Windows.Point,System.Double)">
<summary>
Snaps a screen point to a pixel grid.
</summary>
<remarks>
Depending on the stroke thickness, the point is snapped either to the middle or the border of a pixel.
</remarks>
<param name="x">The x coordinate of the point.</param>
<param name="y">The y coordinate of the point.</param>
<param name="strokeThickness">The stroke thickness.</param>
<param name="visualOffset">A point structure which represents X and Y visual offsets relative to visual root</param>
<param name="dpiScale">The DPI scale.</param>
<returns>Snapped point</returns>
</member>
<member name="M:OxyPlot.Wpf.PixelLayout.Snap(System.Windows.Rect,System.Double,System.Windows.Point,System.Double)">
<summary>
Snaps a rectangle structure to a pixel grid.
</summary>
<remarks>
Depending on the stroke thickness, the rectangle bounds are snapped either to the middle or the border of pixels.
</remarks>
<param name="rect">Rectangle structure</param>
<param name="strokeThickness">The stroke thickness.</param>
<param name="visualOffset">A point structure which represents X and Y visual offsets relative to visual root</param>
<param name="dpiScale">The DPI scale.</param>
<returns>Snapped rectangle structure</returns>
</member>
<member name="M:OxyPlot.Wpf.PixelLayout.SnapStrokeThickness(System.Double,System.Double)">
<summary>
Snaps a stroke thickness to an integer multiple of device pixels.
</summary>
<param name="strokeThickness">The stroke thickness.</param>
<param name="dpiScale">The DPI scale.</param>
<returns>The snapped stroke thickness.</returns>
</member>
<member name="M:OxyPlot.Wpf.PixelLayout.Snap(System.Double,System.Double,System.Double)">
<summary>
Snaps a screen coordinate to a pixel grid
</summary>
<param name="value">Screen coordinate</param>
<param name="offset">Pixel grid offset</param>
<param name="scale">Pixel grid scale</param>
<returns>Snapped coordinate</returns>
</member>
<member name="M:OxyPlot.Wpf.PixelLayout.GetPixelOffset(System.Double,System.Double)">
<summary>
Gets the pixel offset for the given scale and stroke thickness.
</summary>
<remarks>
This takes into account that lines with even width should be rendered on the border between two pixels, while lines with odd width should be rendered
in the middle of a pixel.
</remarks>
<param name="strokeThickness">The stroke thickness.</param>
<param name="scale">Pixel grid scale</param>
<returns>The pixel offset.</returns>
</member>
<member name="T:OxyPlot.Wpf.XamlExporter">
<summary>
Provides functionality to export plots to XAML.
</summary>
</member>
<member name="M:OxyPlot.Wpf.XamlExporter.ExportToString(OxyPlot.IPlotModel,System.Double,System.Double)">
<summary>
Export the specified plot model to an xaml string.
</summary>
<param name="model">The model.</param>
<param name="width">The width.</param>
<param name="height">The height.</param>
<returns>A xaml string.</returns>
</member>
<member name="M:OxyPlot.Wpf.XamlExporter.Export(OxyPlot.PlotModel,System.String,System.Double,System.Double)">
<summary>
Exports the specified plot model to a xaml file.
</summary>
<param name="model">The model.</param>
<param name="fileName">Name of the file.</param>
<param name="width">The width.</param>
<param name="height">The height.</param>
</member>
<member name="M:OxyPlot.Wpf.XamlExporter.Export(OxyPlot.IPlotModel,System.Xml.XmlWriter,System.Double,System.Double)">
<summary>
Exports the specified plot model to a xml writer.
</summary>
<param name="model">The model.</param>
<param name="writer">The xml writer.</param>
<param name="width">The width.</param>
<param name="height">The height.</param>
</member>
<member name="T:OxyPlot.Wpf.XamlRenderContext">
<summary>
Implements <see cref="T:OxyPlot.IRenderContext" /> for <see cref="T:System.Windows.Controls.Canvas" />. This does not use <see cref="T:System.Windows.Media.StreamGeometry"/> and therefore the output can be serialized to XAML.
</summary>
</member>
<member name="F:OxyPlot.Wpf.XamlRenderContext.MaxFiguresPerGeometry">
<summary>
The maximum number of figures per geometry.
</summary>
</member>
<member name="F:OxyPlot.Wpf.XamlRenderContext.MaxPolylinesPerLine">
<summary>
The maximum number of polylines per line.
</summary>
</member>
<member name="F:OxyPlot.Wpf.XamlRenderContext.MinPointsPerPolyline">
<summary>
The minimum number of points per polyline.
</summary>
</member>
<member name="M:OxyPlot.Wpf.XamlRenderContext.#ctor(System.Windows.Controls.Canvas)">
<summary>
Initializes a new instance of the <see cref="T:OxyPlot.Wpf.CanvasRenderContext" /> class.
</summary>
<param name="canvas">The canvas.</param>
</member>
<member name="P:OxyPlot.Wpf.XamlRenderContext.BalancedLineDrawingThicknessLimit">
<summary>
Gets or sets the thickness limit for "balanced" line drawing.
</summary>
</member>
<member name="M:OxyPlot.Wpf.XamlRenderContext.DrawEllipses(System.Collections.Generic.IList{OxyPlot.OxyRect},OxyPlot.OxyColor,OxyPlot.OxyColor,System.Double,OxyPlot.EdgeRenderingMode)">
<inheritdoc/>
</member>
<member name="M:OxyPlot.Wpf.XamlRenderContext.DrawLine(System.Collections.Generic.IList{OxyPlot.ScreenPoint},OxyPlot.OxyColor,System.Double,OxyPlot.EdgeRenderingMode,System.Double[],OxyPlot.LineJoin)">
<inheritdoc/>
</member>
<member name="M:OxyPlot.Wpf.XamlRenderContext.DrawLineSegments(System.Collections.Generic.IList{OxyPlot.ScreenPoint},OxyPlot.OxyColor,System.Double,OxyPlot.EdgeRenderingMode,System.Double[],OxyPlot.LineJoin)">
<inheritdoc/>
</member>
<member name="M:OxyPlot.Wpf.XamlRenderContext.DrawPolygons(System.Collections.Generic.IList{System.Collections.Generic.IList{OxyPlot.ScreenPoint}},OxyPlot.OxyColor,OxyPlot.OxyColor,System.Double,OxyPlot.EdgeRenderingMode,System.Double[],OxyPlot.LineJoin)">
<inheritdoc/>
</member>
<member name="M:OxyPlot.Wpf.XamlRenderContext.DrawRectangles(System.Collections.Generic.IList{OxyPlot.OxyRect},OxyPlot.OxyColor,OxyPlot.OxyColor,System.Double,OxyPlot.EdgeRenderingMode)">
<inheritdoc/>
</member>
<member name="M:OxyPlot.Wpf.XamlRenderContext.DrawLineBalanced(System.Collections.Generic.IList{OxyPlot.ScreenPoint},OxyPlot.OxyColor,System.Double,OxyPlot.EdgeRenderingMode,System.Double[],OxyPlot.LineJoin)">
<summary>
Draws the line using the MaxPolylinesPerLine and MinPointsPerPolyline properties.
</summary>
<param name="points">The points.</param>
<param name="stroke">The stroke color.</param>
<param name="thickness">The thickness.</param>
<param name="edgeRenderingMode">The edge rendering mode.</param>
<param name="dashArray">The dash array. Use <c>null</c> to get a solid line.</param>
<param name="lineJoin">The line join.</param>
</member>
<member name="M:OxyPlot.Wpf.XamlRenderContext.ToPointCollection(System.Collections.Generic.IList{OxyPlot.ScreenPoint},System.Double,OxyPlot.EdgeRenderingMode)">
<summary>
Creates a point collection from the specified points. The points are snapped to pixels if required by the edge rendering mode,
</summary>
<param name="points">The points to convert.</param>
<param name="strokeThickness">The stroke thickness.</param>
<param name="edgeRenderingMode">The edge rendering mode.</param>
<returns>The point collection.</returns>
</member>
<member name="T:OxyPlot.Wpf.XpsExporter">
<summary>
Provides functionality to export plots to xps.
</summary>
</member>
<member name="M:OxyPlot.Wpf.XpsExporter.#ctor">
<summary>
Initializes a new instance of the <see cref="T:OxyPlot.Wpf.XpsExporter" /> class.
</summary>
</member>
<member name="P:OxyPlot.Wpf.XpsExporter.Width">
<summary>
Gets or sets the width of the output document.
</summary>
</member>
<member name="P:OxyPlot.Wpf.XpsExporter.Height">
<summary>
Gets or sets the height of the output document.
</summary>
</member>
<member name="P:OxyPlot.Wpf.XpsExporter.TextFormattingMode">
<summary>
Gets or sets the text formatting mode.
</summary>
<value>The text formatting mode.</value>
</member>
<member name="M:OxyPlot.Wpf.XpsExporter.Export(OxyPlot.IPlotModel,System.String,System.Double,System.Double)">
<summary>
Exports the specified plot model to an xps file.
</summary>
<param name="model">The model.</param>
<param name="fileName">The file name.</param>
<param name="width">The width.</param>
<param name="height">The height.</param>
</member>
<member name="M:OxyPlot.Wpf.XpsExporter.Export(OxyPlot.IPlotModel,System.IO.Stream,System.Double,System.Double)">
<summary>
Exports the specified <see cref="T:OxyPlot.PlotModel" /> to the specified <see cref="T:System.IO.Stream" />.
</summary>
<param name="model">The model.</param>
<param name="stream">The stream.</param>
<param name="width">The width.</param>
<param name="height">The height.</param>
</member>
<member name="M:OxyPlot.Wpf.XpsExporter.Print(OxyPlot.IPlotModel,System.Double,System.Double)">
<summary>
Prints the specified plot model.
</summary>
<param name="model">The model.</param>
<param name="width">The width (using the actual media width if set to NaN).</param>
<param name="height">The height (using the actual media height if set to NaN).</param>
</member>
<member name="M:OxyPlot.Wpf.XpsExporter.Export(OxyPlot.IPlotModel,System.IO.Stream)">
<summary>
Exports the specified <see cref="T:OxyPlot.PlotModel" /> to the specified <see cref="T:System.IO.Stream" />.
</summary>
<param name="model">The model.</param>
<param name="stream">The stream.</param>
</member>
<member name="M:OxyPlot.Wpf.XpsExporter.Print(OxyPlot.IPlotModel)">
<summary>
Prints the specified plot model.
</summary>
<param name="model">The model.</param>
</member>
<member name="M:OxyPlot.Wpf.XpsExporter.Write(OxyPlot.IPlotModel,System.Windows.Xps.XpsDocumentWriter)">
<summary>
Write the specified <see cref="T:OxyPlot.IPlotModel" /> to the specified <see cref="T:System.Windows.Xps.XpsDocumentWriter" />.
</summary>
<param name="model">The model.</param>
<param name="writer">The document writer.</param>
</member>
</members>
</doc>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1,10 +1,11 @@
<UserControl x:Class="Txgy.Controls.CalendarClock2row" <UserControl
x:Class="Txgy.Controls.CalendarClock2row"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:converter="clr-namespace:Txgy.Controls.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Txgy.Controls" xmlns:local="clr-namespace:Txgy.Controls"
xmlns:converter="clr-namespace:Txgy.Controls.Converters" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
FontFamily="Microsoft YaHei" FontFamily="Microsoft YaHei"
mc:Ignorable="d"> mc:Ignorable="d">
<UserControl.Resources> <UserControl.Resources>
@ -21,27 +22,30 @@
<RowDefinition Height="34" /> <RowDefinition Height="34" />
<RowDefinition Height="34" /> <RowDefinition Height="34" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<Label x:Name="lblTime" <Label
x:Name="lblTime"
Grid.RowSpan="2" Grid.RowSpan="2"
Content="00:33:15"
FontSize="28"
Background="{x:Null}" Background="{x:Null}"
BorderThickness="0" BorderThickness="0"
Content="00:33:15"
FontSize="28"
Foreground="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:CalendarClock2row}, Path=ForegroundColor, Converter={StaticResource ctb}}" /> Foreground="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:CalendarClock2row}, Path=ForegroundColor, Converter={StaticResource ctb}}" />
<Label x:Name="lblGL" <Label
x:Name="lblGL"
Grid.Column="1" Grid.Column="1"
Content="公历 2022年4月11日"
FontSize="16"
Background="{x:Null}" Background="{x:Null}"
BorderThickness="0" BorderThickness="0"
Content="公历 2022年4月11日"
FontSize="16"
Foreground="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:CalendarClock2row}, Path=ForegroundColor, Converter={StaticResource ctb}}" /> Foreground="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:CalendarClock2row}, Path=ForegroundColor, Converter={StaticResource ctb}}" />
<Label x:Name="lblNL" <Label
x:Name="lblNL"
Grid.Row="1" Grid.Row="1"
Grid.Column="1" Grid.Column="1"
Content="农历 4月11日 星期日"
FontSize="16"
Background="{x:Null}" Background="{x:Null}"
BorderThickness="0" BorderThickness="0"
Content="农历 4月11日 星期日"
FontSize="16"
Foreground="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:CalendarClock2row}, Path=ForegroundColor, Converter={StaticResource ctb}}" /> Foreground="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:CalendarClock2row}, Path=ForegroundColor, Converter={StaticResource ctb}}" />
</Grid> </Grid>
</UserControl> </UserControl>

@ -1,16 +1,18 @@
<UserControl x:Class="Txgy.Controls.ColorMapBar" <UserControl
x:Class="Txgy.Controls.ColorMapBar"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Txgy.Controls" xmlns:local="clr-namespace:Txgy.Controls"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
x:Name="colorMapBar" x:Name="colorMapBar"
d:Background="Red"
d:DesignHeight="450" d:DesignHeight="450"
d:DesignWidth="800" d:DesignWidth="800"
d:Background="Red"
mc:Ignorable="d"> mc:Ignorable="d">
<Grid> <Grid>
<Rectangle Width="{Binding ElementName=colorMapBar, Path=UcWidth}" <Rectangle
Width="{Binding ElementName=colorMapBar, Path=UcWidth}"
Height="{Binding ElementName=colorMapBar, Path=UcHeight}" Height="{Binding ElementName=colorMapBar, Path=UcHeight}"
HorizontalAlignment="Left" HorizontalAlignment="Left"
d:Fill="Red" d:Fill="Red"
@ -21,6 +23,9 @@
<!--<TextBlock HorizontalAlignment="Right" <!--<TextBlock HorizontalAlignment="Right"
VerticalAlignment="Bottom" VerticalAlignment="Bottom"
Text="{Binding ElementName=colorMapBar, Path=BottomDepth, StringFormat={}{0:D}m}" />--> Text="{Binding ElementName=colorMapBar, Path=BottomDepth, StringFormat={}{0:D}m}" />-->
<TextBlock HorizontalAlignment="Right" VerticalAlignment="Bottom" Text="{Binding ElementName=colorMapBar, Path=BottomDepth, StringFormat={}{0}m}" /> <TextBlock
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Text="{Binding ElementName=colorMapBar, Path=BottomDepth, StringFormat={}{0}m}" />
</Grid> </Grid>
</UserControl> </UserControl>

@ -1,4 +1,3 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<FontFamily x:Key="Iconfont">pack://application:,,,/Txgy.EWS.Client.Assets;component/Fonts/#iconfont</FontFamily> <FontFamily x:Key="Iconfont">pack://application:,,,/Txgy.EWS.Client.Assets;component/Fonts/#iconfont</FontFamily>
</ResourceDictionary> </ResourceDictionary>

@ -1,5 +1,4 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="NormalButtonStyle" TargetType="Button"> <Style x:Key="NormalButtonStyle" TargetType="Button">
<Setter Property="Foreground" Value="White" /> <Setter Property="Foreground" Value="White" />
<Setter Property="Width" Value="50" /> <Setter Property="Width" Value="50" />
@ -9,7 +8,8 @@
<Setter.Value> <Setter.Value>
<ControlTemplate TargetType="Button"> <ControlTemplate TargetType="Button">
<Border Background="{TemplateBinding Background}" CornerRadius="4"> <Border Background="{TemplateBinding Background}" CornerRadius="4">
<Border Name="back" <Border
Name="back"
Background="Transparent" Background="Transparent"
CornerRadius="4"> CornerRadius="4">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" /> <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
@ -37,7 +37,8 @@
<Setter.Value> <Setter.Value>
<ControlTemplate TargetType="Button"> <ControlTemplate TargetType="Button">
<Border Background="{TemplateBinding Background}" CornerRadius="4"> <Border Background="{TemplateBinding Background}" CornerRadius="4">
<Border Name="back" <Border
Name="back"
Background="Transparent" Background="Transparent"
CornerRadius="4"> CornerRadius="4">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" /> <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
@ -64,7 +65,8 @@
<Setter.Value> <Setter.Value>
<ControlTemplate TargetType="Button"> <ControlTemplate TargetType="Button">
<Border Background="{TemplateBinding Background}" CornerRadius="4"> <Border Background="{TemplateBinding Background}" CornerRadius="4">
<Border Name="back" <Border
Name="back"
Background="Transparent" Background="Transparent"
CornerRadius="4"> CornerRadius="4">
<Grid HorizontalAlignment="Center"> <Grid HorizontalAlignment="Center">
@ -72,12 +74,14 @@
<ColumnDefinition Width="auto" /> <ColumnDefinition Width="auto" />
<ColumnDefinition /> <ColumnDefinition />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<TextBlock Margin="5,0" <TextBlock
Margin="5,0"
HorizontalAlignment="Center" HorizontalAlignment="Center"
VerticalAlignment="Center" VerticalAlignment="Center"
Text="{TemplateBinding Tag}" FontFamily="{DynamicResource Iconfont}"
FontFamily="{DynamicResource Iconfont}" /> Text="{TemplateBinding Tag}" />
<ContentPresenter Grid.Column="1" <ContentPresenter
Grid.Column="1"
Margin="0,0,10,0" Margin="0,0,10,0"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" /> VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />

@ -1,54 +1,72 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<SolidColorBrush x:Key="TextBox.Static.Border" Color="#FFABAdB3"/> <SolidColorBrush x:Key="TextBox.Static.Border" Color="#FFABAdB3" />
<SolidColorBrush x:Key="TextBox.MouseOver.Border" Color="#FF7EB4EA"/> <SolidColorBrush x:Key="TextBox.MouseOver.Border" Color="#FF7EB4EA" />
<SolidColorBrush x:Key="TextBox.Focus.Border" Color="#FF569DE5"/> <SolidColorBrush x:Key="TextBox.Focus.Border" Color="#FF569DE5" />
<Style x:Key="SearchTextBoxStyle" TargetType="{x:Type TextBox}"> <Style x:Key="SearchTextBoxStyle" TargetType="{x:Type TextBox}">
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/> <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}" />
<Setter Property="BorderBrush" Value="{StaticResource TextBox.Static.Border}"/> <Setter Property="BorderBrush" Value="{StaticResource TextBox.Static.Border}" />
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/> <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
<Setter Property="BorderThickness" Value="1"/> <Setter Property="BorderThickness" Value="1" />
<Setter Property="KeyboardNavigation.TabNavigation" Value="None"/> <Setter Property="KeyboardNavigation.TabNavigation" Value="None" />
<Setter Property="HorizontalContentAlignment" Value="Left"/> <Setter Property="HorizontalContentAlignment" Value="Left" />
<Setter Property="FocusVisualStyle" Value="{x:Null}"/> <Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="AllowDrop" Value="true"/> <Setter Property="AllowDrop" Value="true" />
<Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/> <Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst" />
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/> <Setter Property="Stylus.IsFlicksEnabled" Value="False" />
<Setter Property="Template"> <Setter Property="Template">
<Setter.Value> <Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}"> <ControlTemplate TargetType="{x:Type TextBox}">
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" <Border
BorderThickness="{TemplateBinding BorderThickness}" x:Name="border"
Height="30"
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
SnapsToDevicePixels="True" BorderBrush="{TemplateBinding BorderBrush}"
CornerRadius="5" Height="30"> BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="5"
SnapsToDevicePixels="True">
<Grid> <Grid>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="30"/> <ColumnDefinition Width="30" />
<ColumnDefinition/> <ColumnDefinition />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<TextBlock Text="&#xe601;" FontFamily="{DynamicResource Iconfont}" <TextBlock
VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="#999" FontSize="14"/> HorizontalAlignment="Center"
<TextBlock Text="输入关键词查找" VerticalAlignment="Center" Margin="3,0" FontSize="12" VerticalAlignment="Center"
Foreground="#999" Grid.Column="1" Visibility="Collapsed" Name="mask"/> FontFamily="{DynamicResource Iconfont}"
<ScrollViewer x:Name="PART_ContentHost" Grid.Column="1" Focusable="false" FontSize="14"
Foreground="#999"
Text="&#xe601;" />
<TextBlock
Name="mask"
Grid.Column="1"
Margin="3,0"
VerticalAlignment="Center"
FontSize="12"
Foreground="#999"
Text="输入关键词查找"
Visibility="Collapsed" />
<ScrollViewer
x:Name="PART_ContentHost"
Grid.Column="1"
VerticalAlignment="Center" VerticalAlignment="Center"
HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/> Focusable="false"
HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Hidden" />
</Grid> </Grid>
</Border> </Border>
<ControlTemplate.Triggers> <ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false"> <Trigger Property="IsEnabled" Value="false">
<Setter Property="Opacity" TargetName="border" Value="0.56"/> <Setter TargetName="border" Property="Opacity" Value="0.56" />
</Trigger> </Trigger>
<Trigger Property="IsMouseOver" Value="true"> <Trigger Property="IsMouseOver" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource TextBox.MouseOver.Border}"/> <Setter TargetName="border" Property="BorderBrush" Value="{StaticResource TextBox.MouseOver.Border}" />
</Trigger> </Trigger>
<Trigger Property="IsKeyboardFocused" Value="true"> <Trigger Property="IsKeyboardFocused" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource TextBox.Focus.Border}"/> <Setter TargetName="border" Property="BorderBrush" Value="{StaticResource TextBox.Focus.Border}" />
</Trigger> </Trigger>
<DataTrigger Binding="{Binding Text,RelativeSource={RelativeSource Self}}" Value=""> <DataTrigger Binding="{Binding Text, RelativeSource={RelativeSource Self}}" Value="">
<Setter Property="Visibility" Value="Visible" TargetName="mask"/> <Setter TargetName="mask" Property="Visibility" Value="Visible" />
</DataTrigger> </DataTrigger>
</ControlTemplate.Triggers> </ControlTemplate.Triggers>
</ControlTemplate> </ControlTemplate>
@ -57,49 +75,57 @@
<Style.Triggers> <Style.Triggers>
<MultiTrigger> <MultiTrigger>
<MultiTrigger.Conditions> <MultiTrigger.Conditions>
<Condition Property="IsInactiveSelectionHighlightEnabled" Value="true"/> <Condition Property="IsInactiveSelectionHighlightEnabled" Value="true" />
<Condition Property="IsSelectionActive" Value="false"/> <Condition Property="IsSelectionActive" Value="false" />
</MultiTrigger.Conditions> </MultiTrigger.Conditions>
<Setter Property="SelectionBrush" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/> <Setter Property="SelectionBrush" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}" />
</MultiTrigger> </MultiTrigger>
</Style.Triggers> </Style.Triggers>
</Style> </Style>
<Style TargetType="TextBox" x:Key="NormalTextBoxStyle"> <Style x:Key="NormalTextBoxStyle" TargetType="TextBox">
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/> <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}" />
<Setter Property="BorderBrush" Value="{StaticResource TextBox.Static.Border}"/> <Setter Property="BorderBrush" Value="{StaticResource TextBox.Static.Border}" />
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/> <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
<Setter Property="BorderThickness" Value="1"/> <Setter Property="BorderThickness" Value="1" />
<Setter Property="KeyboardNavigation.TabNavigation" Value="None"/> <Setter Property="KeyboardNavigation.TabNavigation" Value="None" />
<Setter Property="HorizontalContentAlignment" Value="Left"/> <Setter Property="HorizontalContentAlignment" Value="Left" />
<Setter Property="FocusVisualStyle" Value="{x:Null}"/> <Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="AllowDrop" Value="true"/> <Setter Property="AllowDrop" Value="true" />
<Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/> <Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst" />
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/> <Setter Property="Stylus.IsFlicksEnabled" Value="False" />
<Setter Property="Template"> <Setter Property="Template">
<Setter.Value> <Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}"> <ControlTemplate TargetType="{x:Type TextBox}">
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" <Border
BorderThickness="{TemplateBinding BorderThickness}" x:Name="border"
Height="30"
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
SnapsToDevicePixels="True" BorderBrush="{TemplateBinding BorderBrush}"
CornerRadius="5" Height="30"> BorderThickness="{TemplateBinding BorderThickness}"
<ScrollViewer x:Name="PART_ContentHost" Grid.Column="1" Focusable="false" CornerRadius="5"
VerticalAlignment="Center" Margin="5,0" SnapsToDevicePixels="True">
HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/> <ScrollViewer
x:Name="PART_ContentHost"
Grid.Column="1"
Margin="5,0"
VerticalAlignment="Center"
Focusable="false"
HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Hidden" />
</Border> </Border>
<ControlTemplate.Triggers> <ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false"> <Trigger Property="IsEnabled" Value="false">
<Setter Property="Opacity" TargetName="border" Value="0.56"/> <Setter TargetName="border" Property="Opacity" Value="0.56" />
</Trigger> </Trigger>
<Trigger Property="IsMouseOver" Value="true"> <Trigger Property="IsMouseOver" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource TextBox.MouseOver.Border}"/> <Setter TargetName="border" Property="BorderBrush" Value="{StaticResource TextBox.MouseOver.Border}" />
</Trigger> </Trigger>
<Trigger Property="IsKeyboardFocused" Value="true"> <Trigger Property="IsKeyboardFocused" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource TextBox.Focus.Border}"/> <Setter TargetName="border" Property="BorderBrush" Value="{StaticResource TextBox.Focus.Border}" />
</Trigger> </Trigger>
<Trigger Property="IsReadOnly" Value="True"> <Trigger Property="IsReadOnly" Value="True">
<Setter TargetName="border" Property="Background" Value="#F7F9FA"/> <Setter TargetName="border" Property="Background" Value="#F7F9FA" />
</Trigger> </Trigger>
</ControlTemplate.Triggers> </ControlTemplate.Triggers>
</ControlTemplate> </ControlTemplate>
@ -108,10 +134,10 @@
<Style.Triggers> <Style.Triggers>
<MultiTrigger> <MultiTrigger>
<MultiTrigger.Conditions> <MultiTrigger.Conditions>
<Condition Property="IsInactiveSelectionHighlightEnabled" Value="true"/> <Condition Property="IsInactiveSelectionHighlightEnabled" Value="true" />
<Condition Property="IsSelectionActive" Value="false"/> <Condition Property="IsSelectionActive" Value="false" />
</MultiTrigger.Conditions> </MultiTrigger.Conditions>
<Setter Property="SelectionBrush" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/> <Setter Property="SelectionBrush" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}" />
</MultiTrigger> </MultiTrigger>
</Style.Triggers> </Style.Triggers>
</Style> </Style>

@ -1,3 +1,5 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace Txgy.EWS.Client.Common namespace Txgy.EWS.Client.Common
@ -39,8 +41,14 @@ namespace Txgy.EWS.Client.Common
public bool IsDesign { get; set; } public bool IsDesign { get; set; }
public bool IsRealtime { get; set; } public bool IsRealtime { get; set; }
public int RefreshInterval { get; set; } public int RefreshInterval { get; set; }
public int EventShowTotalSeconds { get; set; } public double DataLookbackHours { get; set; }
public int LoadDataTimeLenMins { get; set; }
[JsonIgnore]
public int EventShowTotalSeconds => (int)Math.Round(DataLookbackHours * 3600.0);
[JsonIgnore]
public int LoadDataTimeLenMins => (int)Math.Round(DataLookbackHours * 60.0);
public int DataCacheTimeLenMins { get; set; } public int DataCacheTimeLenMins { get; set; }
} }

@ -1,5 +1,6 @@
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
@ -33,6 +34,7 @@ namespace Txgy.EWS.Client.Common
var json = File.ReadAllText(ConfigPath); var json = File.ReadAllText(ConfigPath);
var config = JsonConvert.DeserializeObject<BusinessConfig>(json); var config = JsonConvert.DeserializeObject<BusinessConfig>(json);
NormalizeRuntimeSettings(config);
Validate(config); Validate(config);
return config; return config;
} }
@ -48,6 +50,20 @@ namespace Txgy.EWS.Client.Common
} }
} }
public static BusinessConfig Save(BusinessConfig config)
{
lock (SyncRoot)
{
NormalizeRuntimeSettings(config);
Validate(config);
SaveConfig(config);
_current = Read();
FreeSqlTencent.Reset();
FreeSqlLocalSqLite.Reset();
return _current;
}
}
public static string GetConnectionString(string name) public static string GetConnectionString(string name)
{ {
var connections = Current.Database.Connections; var connections = Current.Database.Connections;
@ -105,14 +121,25 @@ namespace Txgy.EWS.Client.Common
} }
public static void UpdateRuntimeSettings(int loadDataTimeLenMins, int dataCacheTimeLenMins) public static void UpdateRuntimeSettings(int loadDataTimeLenMins, int dataCacheTimeLenMins)
{
UpdateDataLookbackHours(loadDataTimeLenMins / 60.0);
}
public static void UpdateDataLookbackHours(double dataLookbackHours)
{ {
lock (SyncRoot) lock (SyncRoot)
{ {
if (dataLookbackHours <= 0)
{
throw new InvalidOperationException("runtime.dataLookbackHours must be greater than 0.");
}
var root = ReadRoot(); var root = ReadRoot();
root["runtime"]["loadDataTimeLenMins"] = loadDataTimeLenMins; root["runtime"]["dataLookbackHours"] = dataLookbackHours;
root["runtime"]["dataCacheTimeLenMins"] = dataCacheTimeLenMins; root["runtime"]["dataCacheTimeLenMins"] = (int)Math.Round(dataLookbackHours * 60.0);
SaveRoot(root); SaveRoot(root);
_current = root.ToObject<BusinessConfig>(); _current = root.ToObject<BusinessConfig>();
NormalizeRuntimeSettings(_current);
Validate(_current); Validate(_current);
} }
} }
@ -127,6 +154,29 @@ namespace Txgy.EWS.Client.Common
return JObject.Parse(File.ReadAllText(ConfigPath)); return JObject.Parse(File.ReadAllText(ConfigPath));
} }
private static void SaveConfig(BusinessConfig config)
{
var serializer = JsonSerializer.Create(new JsonSerializerSettings
{
Formatting = Formatting.Indented,
StringEscapeHandling = StringEscapeHandling.EscapeNonAscii,
ContractResolver = new DefaultContractResolver
{
NamingStrategy = new CamelCaseNamingStrategy
{
ProcessDictionaryKeys = false
}
}
});
string json;
using (var writer = new StringWriter())
{
serializer.Serialize(writer, config);
json = writer.ToString();
}
WriteJson(json);
}
private static void SaveRoot(JObject root) private static void SaveRoot(JObject root)
{ {
var serializer = JsonSerializer.Create(new JsonSerializerSettings var serializer = JsonSerializer.Create(new JsonSerializerSettings
@ -140,11 +190,31 @@ namespace Txgy.EWS.Client.Common
serializer.Serialize(writer, root); serializer.Serialize(writer, root);
json = writer.ToString(); json = writer.ToString();
} }
WriteJson(json);
}
private static void WriteJson(string json)
{
var directory = Path.GetDirectoryName(ConfigPath);
if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
var tempPath = ConfigPath + ".tmp"; var tempPath = ConfigPath + ".tmp";
File.WriteAllText(tempPath, json); File.WriteAllText(tempPath, json, System.Text.Encoding.UTF8);
if (File.Exists(ConfigPath)) if (File.Exists(ConfigPath))
{ {
File.Delete(ConfigPath); var backupPath = ConfigPath + ".bak";
if (File.Exists(backupPath))
{
File.Delete(backupPath);
}
File.Replace(tempPath, ConfigPath, backupPath, true);
if (File.Exists(backupPath))
{
File.Delete(backupPath);
}
return;
} }
File.Move(tempPath, ConfigPath); File.Move(tempPath, ConfigPath);
} }
@ -174,8 +244,7 @@ namespace Txgy.EWS.Client.Common
{ "IsDesign", root["runtime"]?["isDesign"] }, { "IsDesign", root["runtime"]?["isDesign"] },
{ "IsRealtime", root["runtime"]?["isRealtime"] }, { "IsRealtime", root["runtime"]?["isRealtime"] },
{ "RefreshInterval", root["runtime"]?["refreshInterval"] }, { "RefreshInterval", root["runtime"]?["refreshInterval"] },
{ "EventShowTotalSeconds", root["runtime"]?["eventShowTotalSeconds"] }, { "DataLookbackHours", root["runtime"]?["dataLookbackHours"] },
{ "LoadDataTimeLenMins", root["runtime"]?["loadDataTimeLenMins"] },
{ "DataCacheTimeLenMins", root["runtime"]?["dataCacheTimeLenMins"] }, { "DataCacheTimeLenMins", root["runtime"]?["dataCacheTimeLenMins"] },
{ "RealtimeResultTable", root["database"]?["tables"]?["realtimeResultTable"] }, { "RealtimeResultTable", root["database"]?["tables"]?["realtimeResultTable"] },
{ "RealtimeWaveDataTable", root["database"]?["tables"]?["realtimeWaveDataTable"] }, { "RealtimeWaveDataTable", root["database"]?["tables"]?["realtimeWaveDataTable"] },
@ -244,6 +313,23 @@ namespace Txgy.EWS.Client.Common
Require(config.Database?.Tables?.PostFocalmechanismTable, "database.tables.postFocalmechanismTable"); Require(config.Database?.Tables?.PostFocalmechanismTable, "database.tables.postFocalmechanismTable");
GetConnectionStringFromConfig(config, "TencetnMySQL"); GetConnectionStringFromConfig(config, "TencetnMySQL");
GetConnectionStringFromConfig(config, "NasMySQL"); GetConnectionStringFromConfig(config, "NasMySQL");
DateTime.Parse(config.Report.DailyReportStartTime);
}
private static void NormalizeRuntimeSettings(BusinessConfig config)
{
if (config?.Runtime == null)
{
return;
}
var runtime = config.Runtime;
if (runtime.DataLookbackHours <= 0)
{
throw new InvalidOperationException("runtime.dataLookbackHours must be greater than 0.");
}
runtime.DataCacheTimeLenMins = (int)Math.Round(runtime.DataLookbackHours * 60.0);
} }
private static void Require(string value, string name) private static void Require(string value, string name)

@ -82,15 +82,32 @@ namespace Txgy.EWS.Client.Common
} }
private static int _loadDataTimeLenMins = 720; private static int _loadDataTimeLenMins = 720;
private static double _dataLookbackHours = 12;
public static double DataLookbackHours
{
get { return _dataLookbackHours; }
set
{
if (value <= 0)
{
throw new InvalidOperationException("数据回看时长必须大于 0。");
}
_dataLookbackHours = value;
_loadDataTimeLenMins = (int)Math.Round(value * 60.0);
_dataCacheTimeLenMins = _loadDataTimeLenMins;
StaticPropertyChanged?.Invoke(null, new PropertyChangedEventArgs("DataLookbackHours"));
StaticPropertyChanged?.Invoke(null, new PropertyChangedEventArgs("LoadDataTimeLenMins"));
StaticPropertyChanged?.Invoke(null, new PropertyChangedEventArgs("DataCacheTimeLenMins"));
BusinessConfigManager.UpdateDataLookbackHours(value);
}
}
//程序启动时,数据加载时间 //程序启动时,数据加载时间
public static int LoadDataTimeLenMins public static int LoadDataTimeLenMins
{ {
get { return _loadDataTimeLenMins; } get { return _loadDataTimeLenMins; }
set { set {
_loadDataTimeLenMins = value; DataLookbackHours = value / 60.0;
StaticPropertyChanged?.Invoke(null, new PropertyChangedEventArgs("LoadDataTimeLenMins"));
BusinessConfigManager.UpdateRuntimeSettings(LoadDataTimeLenMins, DataCacheTimeLenMins);
} }
} }
private static int _dataCacheTimeLenMins = 720; private static int _dataCacheTimeLenMins = 720;
@ -100,21 +117,59 @@ namespace Txgy.EWS.Client.Common
{ {
get { return _dataCacheTimeLenMins; } get { return _dataCacheTimeLenMins; }
set { set {
_dataCacheTimeLenMins = value; DataLookbackHours = value / 60.0;
StaticPropertyChanged?.Invoke(null, new PropertyChangedEventArgs("DataCacheTimeLenMins"));
BusinessConfigManager.UpdateRuntimeSettings(LoadDataTimeLenMins, DataCacheTimeLenMins);
} }
} }
public static void InitializeRuntimeSettings(RuntimeSettings runtime) public static void InitializeRuntimeSettings(RuntimeSettings runtime)
{ {
IsDesign = runtime.IsDesign; IsDesign = runtime.IsDesign;
_dataLookbackHours = runtime.DataLookbackHours;
_loadDataTimeLenMins = runtime.LoadDataTimeLenMins; _loadDataTimeLenMins = runtime.LoadDataTimeLenMins;
_dataCacheTimeLenMins = runtime.DataCacheTimeLenMins; _dataCacheTimeLenMins = runtime.DataCacheTimeLenMins;
StaticPropertyChanged?.Invoke(null, new PropertyChangedEventArgs("DataLookbackHours"));
StaticPropertyChanged?.Invoke(null, new PropertyChangedEventArgs("LoadDataTimeLenMins")); StaticPropertyChanged?.Invoke(null, new PropertyChangedEventArgs("LoadDataTimeLenMins"));
StaticPropertyChanged?.Invoke(null, new PropertyChangedEventArgs("DataCacheTimeLenMins")); StaticPropertyChanged?.Invoke(null, new PropertyChangedEventArgs("DataCacheTimeLenMins"));
} }
public static void ApplyBusinessConfig(BusinessConfig config)
{
InitializeRuntimeSettings(config.Runtime);
SystemNameCN = config.Branding.SystemNameCn;
SystemNameEN = config.Branding.SystemNameEn;
CommpanyName = config.Branding.CommpanyName;
WorkAreaName = config.Branding.WorkAreaName;
SystemShortName = config.Branding.SystemShortName;
IsRealtime = config.Runtime.IsRealtime;
BaseX = config.Coordinates.BaseX;
BaseY = config.Coordinates.BaseY;
BaseZ = config.Coordinates.BaseZ;
DailyReportStartTime = DateTime.Parse(config.Report.DailyReportStartTime);
DailyReportPlanOffX = config.Report.DailyReportPlanOffsetX;
DailyReportPlanOffY = config.Report.DailyReportPlanOffsetY;
ApplyTableSettings(config);
}
private static void ApplyTableSettings(BusinessConfig config)
{
if (IsRealtime)
{
UseResultTable = config.Database.Tables.RealtimeResultTable;
UseFocalMechanismTable = config.Database.Tables.RealtimeFocalmechanismTable;
UseWaveDataTable = config.Database.Tables.RealtimeWaveDataTable;
DataTypeString = "A";
EventIDColName = "RTEventID";
}
else
{
UseResultTable = config.Database.Tables.PostResultTable;
UseFocalMechanismTable = config.Database.Tables.PostFocalmechanismTable;
UseWaveDataTable = config.Database.Tables.PostWaveDataTable;
DataTypeString = "B";
EventIDColName = "PostEventID";
}
}
private static bool _isInitializing=false; private static bool _isInitializing=false;
public static bool IsInitializing public static bool IsInitializing
{ {
@ -193,11 +248,7 @@ namespace Txgy.EWS.Client.Common
public static void ReadConfig() public static void ReadConfig()
{ {
var config = BusinessConfigManager.Current; var config = BusinessConfigManager.Current;
GlobalConfig.SystemNameCN = config.Branding.SystemNameCn; ApplyBusinessConfig(config);
GlobalConfig.SystemNameEN = config.Branding.SystemNameEn;
GlobalConfig.CommpanyName = config.Branding.CommpanyName;
GlobalConfig.WorkAreaName = config.Branding.WorkAreaName;
GlobalConfig.SystemShortName = config.Branding.SystemShortName;
string jsonText; string jsonText;
//读取工区配置文件 //读取工区配置文件
using (System.IO.StreamReader sr = new System.IO.StreamReader(AppDomain.CurrentDomain.BaseDirectory + using (System.IO.StreamReader sr = new System.IO.StreamReader(AppDomain.CurrentDomain.BaseDirectory +
@ -246,23 +297,7 @@ namespace Txgy.EWS.Client.Common
DailyReportPlanOffY = config.Report.DailyReportPlanOffsetY; DailyReportPlanOffY = config.Report.DailyReportPlanOffsetY;
//Console.WriteLine(DailyReportStartTime.ToString()); //Console.WriteLine(DailyReportStartTime.ToString());
//设置实时监测数据配置文件 //设置实时监测数据配置文件
IsRealtime = config.Runtime.IsRealtime; ApplyTableSettings(config);
if (IsRealtime)
{
UseResultTable = config.Database.Tables.RealtimeResultTable;
UseFocalMechanismTable = config.Database.Tables.RealtimeFocalmechanismTable;
UseWaveDataTable= config.Database.Tables.RealtimeWaveDataTable;
DataTypeString = "A";
EventIDColName = "RTEventID";
}
else
{
UseResultTable = config.Database.Tables.PostResultTable;
UseFocalMechanismTable = config.Database.Tables.PostFocalmechanismTable;
UseWaveDataTable = config.Database.Tables.PostWaveDataTable;
DataTypeString = "B";
EventIDColName = "PostEventID";
}
ProjectConfig.CadFileName = AppDomain.CurrentDomain.BaseDirectory + ProjectConfig.CadFileName = AppDomain.CurrentDomain.BaseDirectory +
config.Paths.CadDwgFilePath; config.Paths.CadDwgFilePath;

@ -319,6 +319,11 @@ namespace Txgy.EWS.Client.Common.Helpers
{ {
foreach (GridItemEventResult item in events) foreach (GridItemEventResult item in events)
{ {
if ((inTime - DateTime.Parse(item.EventTime)).TotalSeconds > EventShowTotalSeconds)
{
continue;
}
TaggedVisual visualE = new TaggedVisual(); TaggedVisual visualE = new TaggedVisual();
using (DrawingContext dc = visualE.RenderOpen()) using (DrawingContext dc = visualE.RenderOpen())
@ -521,7 +526,7 @@ namespace Txgy.EWS.Client.Common.Helpers
{ {
foreach (var item in events) foreach (var item in events)
{ {
if ((DateTime.Parse(item.EventTime) - inTime).TotalSeconds < EventShowTotalSeconds) if ((inTime - DateTime.Parse(item.EventTime)).TotalSeconds <= EventShowTotalSeconds)
{ {
float sizeFactor = (float)(((4f + item.ML) / (10f)) * 10f) + 0.1f; float sizeFactor = (float)(((4f + item.ML) / (10f)) * 10f) + 0.1f;

@ -0,0 +1,8 @@
using Prism.Events;
namespace Txgy.EWS.Client.Common.MessageEvents
{
public class BusinessConfigChangedEvent : PubSubEvent<BusinessConfig>
{
}
}

@ -0,0 +1,8 @@
using Prism.Events;
namespace Txgy.EWS.Client.Common.MessageEvents
{
public class ClearWarningDataEvent : PubSubEvent
{
}
}

@ -0,0 +1,8 @@
using Prism.Events;
namespace Txgy.EWS.Client.Common.MessageEvents
{
public class ReloadWarningDataEvent : PubSubEvent
{
}
}

@ -189,10 +189,13 @@
<Compile Include="Extensions\PrismManager.cs" /> <Compile Include="Extensions\PrismManager.cs" />
<Compile Include="IDialogHostAware.cs" /> <Compile Include="IDialogHostAware.cs" />
<Compile Include="IDialogHostService.cs" /> <Compile Include="IDialogHostService.cs" />
<Compile Include="MessageEvents\ClearWarningDataEvent.cs" />
<Compile Include="MessageEvents\CloseWindowEvent.cs" /> <Compile Include="MessageEvents\CloseWindowEvent.cs" />
<Compile Include="MessageEvents\BusinessConfigChangedEvent.cs" />
<Compile Include="MessageEvents\LoadingEvent.cs" /> <Compile Include="MessageEvents\LoadingEvent.cs" />
<Compile Include="MessageEvents\MessageEvent.cs" /> <Compile Include="MessageEvents\MessageEvent.cs" />
<Compile Include="MessageEvents\ReloadEvent.cs" /> <Compile Include="MessageEvents\ReloadEvent.cs" />
<Compile Include="MessageEvents\ReloadWarningDataEvent.cs" />
<Compile Include="MessageEvents\SelectQueryEventMessage.cs" /> <Compile Include="MessageEvents\SelectQueryEventMessage.cs" />
<Compile Include="MessageEvents\SelectAlarmEventMessage.cs" /> <Compile Include="MessageEvents\SelectAlarmEventMessage.cs" />
<Compile Include="MessageEvents\ShowWavesEvent.cs" /> <Compile Include="MessageEvents\ShowWavesEvent.cs" />

@ -14,6 +14,8 @@ namespace Txgy.EWS.Client.MainModule.ViewModels
{ {
public class TreeMenuViewModel : BindableBase public class TreeMenuViewModel : BindableBase
{ {
private const string SystemSettingsTargetView = "SystemSettingsView";
public List<MenuItemModel> Menus { get; set; } = new List<MenuItemModel>(); public List<MenuItemModel> Menus { get; set; } = new List<MenuItemModel>();
private List<MenuEntity> origMenus = null; private List<MenuEntity> origMenus = null;
@ -29,6 +31,8 @@ namespace Txgy.EWS.Client.MainModule.ViewModels
origMenus = GlobalData.CurrentUserInfo.Menus; origMenus = GlobalData.CurrentUserInfo.Menus;
this.FillMenus(Menus, 0); this.FillMenus(Menus, 0);
} }
AddLocalSystemSettingsMenu();
} }
///递归 ///递归
@ -53,5 +57,44 @@ namespace Txgy.EWS.Client.MainModule.ViewModels
} }
} }
} }
private void AddLocalSystemSettingsMenu()
{
if (ContainsTargetView(Menus, SystemSettingsTargetView))
{
return;
}
Menus.Add(new MenuItemModel(_regionManager)
{
MenuHeader = "系统设置",
MenuIcon = "\ue64c",
TargetView = SystemSettingsTargetView,
Children = new List<MenuItemModel>()
});
}
private bool ContainsTargetView(IEnumerable<MenuItemModel> menus, string targetView)
{
if (menus == null)
{
return false;
}
foreach (var menu in menus)
{
if (string.Equals(menu.TargetView, targetView, StringComparison.OrdinalIgnoreCase))
{
return true;
}
if (ContainsTargetView(menu.Children, targetView))
{
return true;
}
}
return false;
}
} }
} }

@ -655,6 +655,7 @@ namespace Txgy.EWS.Client.PageModule.ViewModels
//ReceviedEvents = new ObservableCollection<GridItemEventResult>(); //ReceviedEvents = new ObservableCollection<GridItemEventResult>();
//AlarmEvents = new ObservableCollection<GridItemEventResult>(); //AlarmEvents = new ObservableCollection<GridItemEventResult>();
}); });
this._ea.GetEvent<ClearWarningDataEvent>().Subscribe(ClearWarningData, ThreadOption.UIThread);
//更新接收到的事件 //更新接收到的事件
this._ea.GetEvent<UpdateReceivedEventMessage>().Subscribe(gier => this._ea.GetEvent<UpdateReceivedEventMessage>().Subscribe(gier =>
{ {
@ -662,7 +663,7 @@ namespace Txgy.EWS.Client.PageModule.ViewModels
{ {
//从接收事件列表中删除超过指定时间范围的数据 //从接收事件列表中删除超过指定时间范围的数据
var timeoutReceivedEvents = ReceviedEvents.Where(re => var timeoutReceivedEvents = ReceviedEvents.Where(re =>
(DateTime.Now - DateTime.Parse(re.EventTime)).TotalSeconds >= GlobalData.EventShowTimeout).ToArray(); (DateTime.Now - DateTime.Parse(re.EventTime)).TotalHours >= GlobalConfig.DataLookbackHours).ToArray();
_dispatcher.Invoke(new System.Action(() => _dispatcher.Invoke(new System.Action(() =>
{ {
if (timeoutReceivedEvents.Length > 0) if (timeoutReceivedEvents.Length > 0)
@ -690,7 +691,7 @@ namespace Txgy.EWS.Client.PageModule.ViewModels
if (!GlobalConfig.IsDesign) if (!GlobalConfig.IsDesign)
{ {
var timeoutAlarmEvents = AlarmEvents.Where(re => var timeoutAlarmEvents = AlarmEvents.Where(re =>
(DateTime.Now - DateTime.Parse(re.EventTime)).TotalSeconds >= GlobalConfig.DataCacheTimeLenMins*60).ToArray(); (DateTime.Now - DateTime.Parse(re.EventTime)).TotalHours >= GlobalConfig.DataLookbackHours).ToArray();
_dispatcher.Invoke(new System.Action(() => _dispatcher.Invoke(new System.Action(() =>
{ {
if (timeoutAlarmEvents.Length > 0) if (timeoutAlarmEvents.Length > 0)
@ -713,6 +714,19 @@ namespace Txgy.EWS.Client.PageModule.ViewModels
}); });
} }
private void ClearWarningData()
{
AlarmEvents.Clear();
ReceviedEvents.Clear();
ListEnergy.Clear();
ListML.Clear();
ListDominantFreq.Clear();
LastAlarmEventEnergy = 0;
LastAlarmEventML = 0;
LastAlarmEventDominFreq = 0;
EnergyMaxY = 2000;
}
private void ListEnergy_NoisyCollectionChanged(IEnumerable<ObservableValue> oldItems, IEnumerable<ObservableValue> newItems) private void ListEnergy_NoisyCollectionChanged(IEnumerable<ObservableValue> oldItems, IEnumerable<ObservableValue> newItems)
{ {
if (ListEnergy.Count > TableShowCount) if (ListEnergy.Count > TableShowCount)

@ -37,6 +37,9 @@ namespace Txgy.EWS.Client.PageModule.ViewModels
private readonly ILogHelper _logHelper; private readonly ILogHelper _logHelper;
Dispatcher _dispatcher; Dispatcher _dispatcher;
private bool isCanRun = true; private bool isCanRun = true;
private readonly object _reloadWarningDataSync = new object();
private bool _isReloadingWarningData;
private bool _reloadWarningDataRequested;
SoundPlayer alarmPlayer = new SoundPlayer(); SoundPlayer alarmPlayer = new SoundPlayer();
@ -176,41 +179,75 @@ namespace Txgy.EWS.Client.PageModule.ViewModels
this._ea = ea; this._ea = ea;
this._logHelper = logHelper; this._logHelper = logHelper;
this.searchMsEventBLL = searchMsEventBLL; this.searchMsEventBLL = searchMsEventBLL;
var config = BusinessConfigManager.Current; LoadBusinessConfig(BusinessConfigManager.Current);
//AlarmThreshold = 1000; this._ea.GetEvent<BusinessConfigChangedEvent>().Subscribe(LoadBusinessConfig, ThreadOption.UIThread);
using (System.IO.StreamReader sr = new System.IO.StreamReader(AppDomain.CurrentDomain.BaseDirectory + this._ea.GetEvent<ReloadWarningDataEvent>().Subscribe(() =>
config.Paths.AlarmSetting))
{ {
AlarmSetting = JsonConvert.DeserializeObject<AlarmSetting>(sr.ReadToEnd()); QueueReloadWarningData();
});
ListAlramMusic = new List<string>();
string[] alarmTmpArray = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory + "audio", "*.wav");
for (int i = 0; i < alarmTmpArray.Length; i++)
{
ListAlramMusic.Add(Path.GetFileName(alarmTmpArray[i]));
} }
//AlarmThreshold = AlarmSettingConfig.AlarmThreshold; QueueReloadWarningData();
//RefreshInterval = AlarmSetting.RefreshInterval;
RefreshInterval = config.Runtime.RefreshInterval; //
CurAlarmMusic = AlarmSetting.AlarmSound; }
ListAlarmLevel = new List<AlarmLevelModel>();
using (System.IO.StreamReader sr = new System.IO.StreamReader(AppDomain.CurrentDomain.BaseDirectory + private void QueueReloadWarningData()
config.Paths.AlarmLevelConfig))
{ {
ListAlarmLevel = JsonConvert.DeserializeObject<List<AlarmLevelModel>>(sr.ReadToEnd()); lock (_reloadWarningDataSync)
{
_reloadWarningDataRequested = true;
if (_isReloadingWarningData)
{
return;
} }
CurAlarmLevel = ListAlarmLevel.First(la => la.Level == 1);
_dispatcher.Invoke(new System.Action(() => _isReloadingWarningData = true;
}
Task.Run(async () => await ProcessReloadWarningDataQueueAsync());
}
private async Task ProcessReloadWarningDataQueueAsync()
{ {
GlobalData.CurAlarmLevelValue = CurAlarmLevel.Level; try
GlobalData.CurAlarmLevelColor = new SolidColorBrush((Color)ColorConverter.ConvertFromString(CurAlarmLevel.ColorStr)); {
})); while (true)
{
lock (_reloadWarningDataSync)
{
if (!_reloadWarningDataRequested)
{
return;
}
ListAlramMusic = new List<string>(); _reloadWarningDataRequested = false;
string[] alarmTmpArray = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory + "audio", "*.wav"); }
for (int i = 0; i < alarmTmpArray.Length; i++)
await ReloadWarningDataAsync();
}
}
finally
{ {
ListAlramMusic.Add(Path.GetFileName(alarmTmpArray[i])); lock (_reloadWarningDataSync)
{
_isReloadingWarningData = false;
}
}
} }
private async Task ReloadWarningDataAsync()
{
try
{
GlobalConfig.IsInitializing = true; GlobalConfig.IsInitializing = true;
//初始化检索数据库数据 GlobalConfig.InitializingCounter = 0;
Task.Run(async () => {
string dataFilePath = GlobalConfig.ProjectConfig.MseedFilePath + "\\"; string dataFilePath = GlobalConfig.ProjectConfig.MseedFilePath + "\\";
GlobalData.ListAlarmEventId = new List<int>(); GlobalData.ListAlarmEventId = new List<int>();
@ -218,22 +255,55 @@ namespace Txgy.EWS.Client.PageModule.ViewModels
GlobalData.ReceivedEvents = new List<GridItemEventResult>(); GlobalData.ReceivedEvents = new List<GridItemEventResult>();
GlobalData.LastEvent = new GridItemEventResult(); GlobalData.LastEvent = new GridItemEventResult();
GlobalData.LastEvent.EventID = 0; GlobalData.LastEvent.EventID = 0;
//预警平面参数
GlobalData.AlarmPlanList = new List<Plane>(); GlobalData.AlarmPlanList = new List<Plane>();
GlobalData.MidEventList = new List<GridItemEventResult>(); GlobalData.MidEventList = new List<GridItemEventResult>();
_ea.GetEvent<ClearWarningDataEvent>().Publish();
DateTime timeNow = DateTime.Now; DateTime timeNow = DateTime.Now;
var events = searchMsEventBLL.GetGridEvents(timeNow.AddHours(-GlobalConfig.DataLookbackHours), timeNow, -3, 0);
if (events == null || events.Count == 0)
{
GlobalConfig.InitializingCounter = 100;
return;
}
var events = searchMsEventBLL.GetGridEvents(timeNow.AddMinutes(-GlobalConfig.LoadDataTimeLenMins), timeNow, -3, 0);
for (int i = 0; i < events.Count; i++) for (int i = 0; i < events.Count; i++)
{ {
await searchMsEventBLL.DownloadJsonDataAsync(events[i], dataFilePath, NotifyView); await searchMsEventBLL.DownloadJsonDataAsync(events[i], dataFilePath, NotifyView);
GlobalConfig.InitializingCounter = ((i+1.0)/(double)events.Count)*100.0; GlobalConfig.InitializingCounter = ((i + 1.0) / (double)events.Count) * 100.0;
//await Console.Out.WriteLineAsync(GlobalConfig.InitializingCounter.ToString()); }
}
catch (Exception ex)
{
_logHelper.Error(this, $"刷新预警信息数据失败:{ex.Message}");
}
finally
{
GlobalConfig.IsInitializing = false;
}
} }
}).ContinueWith(t => { GlobalConfig.IsInitializing = false; });
// private void LoadBusinessConfig(BusinessConfig config)
{
using (System.IO.StreamReader sr = new System.IO.StreamReader(AppDomain.CurrentDomain.BaseDirectory +
config.Paths.AlarmSetting))
{
AlarmSetting = JsonConvert.DeserializeObject<AlarmSetting>(sr.ReadToEnd());
}
RefreshInterval = config.Runtime.RefreshInterval;
CurAlarmMusic = AlarmSetting.AlarmSound;
using (System.IO.StreamReader sr = new System.IO.StreamReader(AppDomain.CurrentDomain.BaseDirectory +
config.Paths.AlarmLevelConfig))
{
ListAlarmLevel = JsonConvert.DeserializeObject<List<AlarmLevelModel>>(sr.ReadToEnd());
}
CurAlarmLevel = ListAlarmLevel.First(la => la.Level == 1);
_dispatcher.Invoke(new System.Action(() =>
{
GlobalData.CurAlarmLevelValue = CurAlarmLevel.Level;
GlobalData.CurAlarmLevelColor = new SolidColorBrush((Color)ColorConverter.ConvertFromString(CurAlarmLevel.ColorStr));
}));
} }
void StartMonitorning() void StartMonitorning()
@ -454,7 +524,7 @@ namespace Txgy.EWS.Client.PageModule.ViewModels
gier.DominantFreq = GlobalData.GetDominFreq(gier.EventTime); gier.DominantFreq = GlobalData.GetDominFreq(gier.EventTime);
//从接收事件列表中删除超过指定时间范围的数据 //从接收事件列表中删除超过指定时间范围的数据
var timeoutReceivedEvents = GlobalData.ReceivedEvents.FindAll(re => (DateTime.Now - DateTime.Parse(re.EventTime)).TotalSeconds >= GlobalData.EventShowTimeout).ToArray(); var timeoutReceivedEvents = GlobalData.ReceivedEvents.FindAll(re => (DateTime.Now - DateTime.Parse(re.EventTime)).TotalHours >= GlobalConfig.DataLookbackHours).ToArray();
if (timeoutReceivedEvents.Length > 0) if (timeoutReceivedEvents.Length > 0)
{ {
for (int i = timeoutReceivedEvents.Length - 1; i >= 0; i--) for (int i = timeoutReceivedEvents.Length - 1; i >= 0; i--)
@ -640,7 +710,7 @@ namespace Txgy.EWS.Client.PageModule.ViewModels
if (!GlobalConfig.IsDesign) if (!GlobalConfig.IsDesign)
{ {
//从预警事件列表中删除超过指定时间范围的数据 //从预警事件列表中删除超过指定时间范围的数据
var timeoutAlarmEvents = GlobalData.AlarmEvents.FindAll(re => (DateTime.Now - DateTime.Parse(re.EventTime)).TotalSeconds >= GlobalData.EventShowTimeout).ToArray(); var timeoutAlarmEvents = GlobalData.AlarmEvents.FindAll(re => (DateTime.Now - DateTime.Parse(re.EventTime)).TotalHours >= GlobalConfig.DataLookbackHours).ToArray();
if (timeoutAlarmEvents.Length > 0) if (timeoutAlarmEvents.Length > 0)
{ {
for (int i = timeoutAlarmEvents.Length - 1; i >= 0; i--) for (int i = timeoutAlarmEvents.Length - 1; i >= 0; i--)

@ -498,7 +498,7 @@
Header="所有事件列表" Header="所有事件列表"
Style="{StaticResource MaterialDesignGroupBox}"> Style="{StaticResource MaterialDesignGroupBox}">
<txgycontrols:myListBox x:Name="ReceivedEventListBox" <txgycontrols:myListBox x:Name="ReceivedEventListBox"
Height="574" VerticalAlignment="Stretch"
Background="Transparent" Background="Transparent"
BorderThickness="0" BorderThickness="0"
SelectionMode="Single" SelectionMode="Single"

@ -137,12 +137,18 @@ namespace Txgy.EWS.Client.PageModule.Views
canvas.RenderTransform = transGroup; canvas.RenderTransform = transGroup;
//事件时限秒数 //事件时限秒数
EventShowTotalSeconds = BusinessConfigManager.Current.Runtime.EventShowTotalSeconds; EventShowTotalSeconds = BusinessConfigManager.Current.Runtime.EventShowTotalSeconds;
this._ea.GetEvent<BusinessConfigChangedEvent>().Subscribe(config =>
{
EventShowTotalSeconds = config.Runtime.EventShowTotalSeconds;
RedrawReceivedEvents();
}, ThreadOption.UIThread);
this._ea.GetEvent<ClearWarningDataEvent>().Subscribe(RedrawReceivedEvents, ThreadOption.UIThread);
_handleDataGenerated = new HandleDataGeneratedDelegate(rpi.DrawGierInTime); _handleDataGenerated = new HandleDataGeneratedDelegate(rpi.DrawGierInTime);
//更新接收到的事件到平面图 //更新接收到的事件到平面图
this._ea.GetEvent<UpdateReceivedEventMessage>().Subscribe(u => this._ea.GetEvent<UpdateReceivedEventMessage>().Subscribe(u =>
{ {
_dispatcher.Invoke(_handleDataGenerated, GlobalData.ReceivedEvents, canvas.ActualWidth, canvas.ActualHeight, EventShowTotalSeconds, DateTime.Now); RedrawReceivedEvents();
}); });
//开始监控 //开始监控
//this._ea.GetEvent<StartRunMonitorMessage>().Subscribe(() => //this._ea.GetEvent<StartRunMonitorMessage>().Subscribe(() =>
@ -181,6 +187,16 @@ namespace Txgy.EWS.Client.PageModule.Views
// //_dispatcher.Invoke(_handleDataGenerated); // //_dispatcher.Invoke(_handleDataGenerated);
//}); //});
} }
private void RedrawReceivedEvents()
{
if (_handleDataGenerated == null)
{
return;
}
_dispatcher.Invoke(_handleDataGenerated, GlobalData.ReceivedEvents, canvas.ActualWidth, canvas.ActualHeight, EventShowTotalSeconds, DateTime.Now);
}
//点击事件列表动画效果 //点击事件列表动画效果
public void ClickEventInListStoryBoard(GridItemEventResult gier, int Repeat) public void ClickEventInListStoryBoard(GridItemEventResult gier, int Repeat)
{ {
@ -405,7 +421,7 @@ namespace Txgy.EWS.Client.PageModule.Views
foreach (var item in GlobalData.AlarmEvents) foreach (var item in GlobalData.AlarmEvents)
{ {
//如果事件时间在24小时内显示 //如果事件时间在24小时内显示
if ((DateTime.Parse(item.EventTime) - DateTime.Now).TotalSeconds < EventShowTotalSeconds) if ((DateTime.Now - DateTime.Parse(item.EventTime)).TotalSeconds <= EventShowTotalSeconds)
{ {
float sizeFactor = (float)(((4f + item.ML) / (4f)) * 2f) + 0.1f; float sizeFactor = (float)(((4f + item.ML) / (4f)) * 2f) + 0.1f;
int colorIndex = (int)(((item.Z - GlobalConfig.ProjectConfig.WorkArea.ZMin) int colorIndex = (int)(((item.Z - GlobalConfig.ProjectConfig.WorkArea.ZMin)

@ -133,6 +133,12 @@ namespace Txgy.EWS.Client.PageModule.Views
canvas.RenderTransform = transGroup; canvas.RenderTransform = transGroup;
//事件时限秒数 //事件时限秒数
EventShowTotalSeconds = BusinessConfigManager.Current.Runtime.EventShowTotalSeconds; EventShowTotalSeconds = BusinessConfigManager.Current.Runtime.EventShowTotalSeconds;
this._ea.GetEvent<BusinessConfigChangedEvent>().Subscribe(config =>
{
EventShowTotalSeconds = config.Runtime.EventShowTotalSeconds;
RedrawReceivedEvents();
}, ThreadOption.UIThread);
this._ea.GetEvent<ClearWarningDataEvent>().Subscribe(RedrawReceivedEvents, ThreadOption.UIThread);
_handleDataGenerated = new HandleDataGeneratedDelegate(rpi.DrawGierInTime); _handleDataGenerated = new HandleDataGeneratedDelegate(rpi.DrawGierInTime);
@ -163,6 +169,15 @@ namespace Txgy.EWS.Client.PageModule.Views
// //_dispatcher.Invoke(_handleDataGenerated); // //_dispatcher.Invoke(_handleDataGenerated);
//}); //});
} }
private void RedrawReceivedEvents()
{
if (_handleDataGenerated == null)
{
return;
}
_dispatcher.Invoke(_handleDataGenerated, GlobalData.ReceivedEvents, canvas.ActualWidth, canvas.ActualHeight, EventShowTotalSeconds, DateTime.Now);
}
public void CreateStoryBoard() public void CreateStoryBoard()
{ {
var myCircle = new Ellipse(); var myCircle = new Ellipse();
@ -266,7 +281,7 @@ namespace Txgy.EWS.Client.PageModule.Views
foreach (var item in GlobalData.AlarmEvents) foreach (var item in GlobalData.AlarmEvents)
{ {
//如果事件时间在24小时内显示 //如果事件时间在24小时内显示
if ((DateTime.Parse(item.EventTime) - DateTime.Now).TotalSeconds < EventShowTotalSeconds) if ((DateTime.Now - DateTime.Parse(item.EventTime)).TotalSeconds <= EventShowTotalSeconds)
{ {
float sizeFactor = (float)(((4f + item.ML) / (4f)) * 2f) + 0.1f; float sizeFactor = (float)(((4f + item.ML) / (4f)) * 2f) + 0.1f;
int colorIndex = (int)(((item.Z - GlobalConfig.ProjectConfig.WorkArea.ZMin) int colorIndex = (int)(((item.Z - GlobalConfig.ProjectConfig.WorkArea.ZMin)

@ -168,20 +168,13 @@
SelectedDateTime="{Binding TimeFC.Cond2}" SelectedDateTime="{Binding TimeFC.Cond2}"
FontSize="14" /> FontSize="14" />
<StackPanel Margin="200,0,0,0" HorizontalAlignment="Right" Orientation="Horizontal"> <StackPanel Margin="200,0,0,0" HorizontalAlignment="Right" Orientation="Horizontal">
<TextBlock Margin="5" VerticalAlignment="Center" Text="加载数据时长" /> <TextBlock Margin="5" VerticalAlignment="Center" Text="数据回看时长" />
<TextBox Width="60" <TextBox Width="60"
Margin="5" Margin="5"
d:Text="720" d:Text="12"
Text="{Binding Path=(comm:GlobalConfig.LoadDataTimeLenMins)}" Text="{Binding Path=(comm:GlobalConfig.DataLookbackHours)}"
TextAlignment="Right" /> TextAlignment="Right" />
<TextBlock VerticalAlignment="Center" Text="分钟" /> <TextBlock VerticalAlignment="Center" Text="小时" />
<TextBlock Margin="20,5,5,5" VerticalAlignment="Center" Text="数据缓存时长" />
<TextBox Width="60"
Margin="5"
d:Text="720"
Text="{Binding Path=(comm:GlobalConfig.DataCacheTimeLenMins)}"
TextAlignment="Right" />
<TextBlock VerticalAlignment="Center" Text="分钟" />
<TextBlock Margin="100,0,0,0" VerticalAlignment="Center" Text="V20250704" /> <TextBlock Margin="100,0,0,0" VerticalAlignment="Center" Text="V20250704" />
</StackPanel> </StackPanel>

@ -1,17 +1,18 @@
<UserControl x:Class="Txgy.EWS.Client.PageModule.Views.TitleView" <UserControl
x:Class="Txgy.EWS.Client.PageModule.Views.TitleView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Txgy.EWS.Client.PageModule.Views"
xmlns:controls="clr-namespace:Txgy.Controls;assembly=Txgy.Controls"
xmlns:global="clr-namespace:Txgy.EWS.Client.Common;assembly=Txgy.EWS.Client.Common"
xmlns:comm="clr-namespace:Txgy.EWS.Client.Common;assembly=Txgy.EWS.Client.Common" xmlns:comm="clr-namespace:Txgy.EWS.Client.Common;assembly=Txgy.EWS.Client.Common"
xmlns:controls="clr-namespace:Txgy.Controls;assembly=Txgy.Controls"
xmlns:converter="clr-namespace:Txgy.EWS.Client.Common.Converters;assembly=Txgy.EWS.Client.Common" xmlns:converter="clr-namespace:Txgy.EWS.Client.Common.Converters;assembly=Txgy.EWS.Client.Common"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:global="clr-namespace:Txgy.EWS.Client.Common;assembly=Txgy.EWS.Client.Common"
xmlns:local="clr-namespace:Txgy.EWS.Client.PageModule.Views"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:prism="http://prismlibrary.com/" xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"
d:DesignHeight="100" d:DesignHeight="100"
d:DesignWidth="1530" d:DesignWidth="1530"
prism:ViewModelLocator.AutoWireViewModel="True"
mc:Ignorable="d"> mc:Ignorable="d">
<UserControl.Resources> <UserControl.Resources>
<ResourceDictionary> <ResourceDictionary>
@ -25,7 +26,8 @@
<Setter Property="Template"> <Setter Property="Template">
<Setter.Value> <Setter.Value>
<ControlTemplate TargetType="Button"> <ControlTemplate TargetType="Button">
<ContentPresenter VerticalAlignment="Center" <ContentPresenter
VerticalAlignment="Center"
Content="{TemplateBinding Content}" Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"> ContentTemplate="{TemplateBinding ContentTemplate}">
<ContentPresenter.Resources> <ContentPresenter.Resources>
@ -49,39 +51,44 @@
<Setter Property="Foreground" Value="#FF7A40F2" /> <Setter Property="Foreground" Value="#FF7A40F2" />
</Style> </Style>
<ControlTemplate x:Key="StateButtonTemplate" TargetType="ToggleButton"> <ControlTemplate x:Key="StateButtonTemplate" TargetType="ToggleButton">
<Border Name="back" <Border
Name="back"
Width="102" Width="102"
Height="30" Height="30"
Background="#EEE"
BorderBrush="#99EEEEEE" BorderBrush="#99EEEEEE"
BorderThickness="0" BorderThickness="0"
CornerRadius="3" CornerRadius="3">
Background="#EEE">
<Border.Effect> <Border.Effect>
<BlurEffect Radius="1" /> <BlurEffect Radius="1" />
</Border.Effect> </Border.Effect>
<Grid> <Grid>
<TextBlock Margin="8,0" <TextBlock
Margin="8,0"
HorizontalAlignment="Left" HorizontalAlignment="Left"
VerticalAlignment="Center" VerticalAlignment="Center"
Text="停止"
FontSize="16" FontSize="16"
Foreground="#667A40F2" /> Foreground="#667A40F2"
<TextBlock Margin="4,0" Text="停止" />
<TextBlock
Margin="4,0"
HorizontalAlignment="Right" HorizontalAlignment="Right"
VerticalAlignment="Center" VerticalAlignment="Center"
Text="运行中"
FontSize="16" FontSize="16"
Foreground="#FF7A40F2" /> Foreground="#FF7A40F2"
<Border Width="48" Text="运行中" />
<Border
Width="48"
Margin="2,2" Margin="2,2"
HorizontalAlignment="Left" HorizontalAlignment="Left"
Background="#DDD" Background="#DDD"
CornerRadius="2"> CornerRadius="2">
<TextBlock HorizontalAlignment="Center" <TextBlock
HorizontalAlignment="Center"
VerticalAlignment="Center" VerticalAlignment="Center"
Text="||"
FontSize="16" FontSize="16"
Foreground="#FF673Ab7" /> Foreground="#FF673Ab7"
Text="||" />
<Border.RenderTransform> <Border.RenderTransform>
<TranslateTransform x:Name="tt" X="48" /> <TranslateTransform x:Name="tt" X="48" />
</Border.RenderTransform> </Border.RenderTransform>
@ -93,7 +100,8 @@
<Trigger.EnterActions> <Trigger.EnterActions>
<BeginStoryboard> <BeginStoryboard>
<Storyboard> <Storyboard>
<DoubleAnimation Storyboard.TargetName="tt" <DoubleAnimation
Storyboard.TargetName="tt"
Storyboard.TargetProperty="X" Storyboard.TargetProperty="X"
To="0" To="0"
Duration="0:0:0.2" /> Duration="0:0:0.2" />
@ -101,8 +109,9 @@
</BeginStoryboard> </BeginStoryboard>
<BeginStoryboard> <BeginStoryboard>
<Storyboard> <Storyboard>
<ColorAnimation RepeatBehavior="Forever" <ColorAnimation
AutoReverse="True" AutoReverse="True"
RepeatBehavior="Forever"
Storyboard.TargetName="back" Storyboard.TargetName="back"
Storyboard.TargetProperty="Background.(SolidColorBrush.Color)" Storyboard.TargetProperty="Background.(SolidColorBrush.Color)"
To="Orange" To="Orange"
@ -119,10 +128,12 @@
<Trigger.ExitActions> <Trigger.ExitActions>
<BeginStoryboard> <BeginStoryboard>
<Storyboard> <Storyboard>
<DoubleAnimation Storyboard.TargetName="tt" <DoubleAnimation
Storyboard.TargetName="tt"
Storyboard.TargetProperty="X" Storyboard.TargetProperty="X"
Duration="0:0:0.2" /> Duration="0:0:0.2" />
<ColorAnimation Storyboard.TargetName="back" <ColorAnimation
Storyboard.TargetName="back"
Storyboard.TargetProperty="Background.(SolidColorBrush.Color)" Storyboard.TargetProperty="Background.(SolidColorBrush.Color)"
Duration="0:0:0.2" /> Duration="0:0:0.2" />
</Storyboard> </Storyboard>
@ -131,7 +142,8 @@
</Trigger> </Trigger>
</ControlTemplate.Triggers> </ControlTemplate.Triggers>
</ControlTemplate> </ControlTemplate>
<DataTrigger x:Key="newAlarm" <DataTrigger
x:Key="newAlarm"
Binding="{Binding RunEventCnt}" Binding="{Binding RunEventCnt}"
Value="2"> Value="2">
<DataTrigger.EnterActions> <DataTrigger.EnterActions>
@ -149,61 +161,83 @@
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="350" MinWidth="350" /> <ColumnDefinition Width="350" MinWidth="350" />
<ColumnDefinition MinWidth="160" /> <ColumnDefinition MinWidth="160" />
<ColumnDefinition Width="380" MinWidth="380" /> <ColumnDefinition Width="480" MinWidth="480" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<controls:CalendarClock2row Height="68" <controls:CalendarClock2row
Height="68"
HorizontalAlignment="Center" HorizontalAlignment="Center"
ForegroundColor="Black" /> ForegroundColor="Black" />
<StackPanel Grid.Column="1" <StackPanel
Grid.Column="1"
HorizontalAlignment="Center" HorizontalAlignment="Center"
VerticalAlignment="Center"> VerticalAlignment="Center">
<TextBlock d:Text="煤矿动力灾害微地震实时预警系统" <TextBlock
Text="{Binding Path=(global:GlobalConfig.SystemNameCN)}" d:Text="煤矿动力灾害微地震实时预警系统"
FontSize="34" /> FontSize="34"
<TextBlock HorizontalAlignment="Center" Text="{Binding Path=(global:GlobalConfig.SystemNameCN)}" />
<TextBlock
HorizontalAlignment="Center"
d:Text="Microseismic Real-time Monitoring System" d:Text="Microseismic Real-time Monitoring System"
Text="{Binding Path=(global:GlobalConfig.SystemNameEN)}" FontSize="24"
FontSize="24" /> Text="{Binding Path=(global:GlobalConfig.SystemNameEN)}" />
</StackPanel> </StackPanel>
<Grid Grid.Column="2" Height="68"> <Grid Grid.Column="2" Height="68">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="260" />
<ColumnDefinition /> <ColumnDefinition />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition /> <RowDefinition />
<RowDefinition /> <RowDefinition />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<TextBlock VerticalAlignment="Center" <TextBlock
VerticalAlignment="Center"
FontSize="18" FontSize="18"
Text="运行时长:" /> Text="运行时长:" />
<TextBlock VerticalAlignment="Center" <TextBlock
VerticalAlignment="Center"
d:Text="1天22小时15分20秒" d:Text="1天22小时15分20秒"
FontSize="18" FontSize="18"
Text="{Binding RunSpan}" /> Text="{Binding RunSpan}" />
</StackPanel> </StackPanel>
<StackPanel Grid.Row="1" Orientation="Horizontal"> <StackPanel Grid.Row="1" Orientation="Horizontal">
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<TextBlock VerticalAlignment="Center" <TextBlock
Text="事件数量:" VerticalAlignment="Center"
FontSize="14" /> FontSize="14"
<TextBlock VerticalAlignment="Center" Text="事件数量:" />
<TextBlock
VerticalAlignment="Center"
d:Text="10000" d:Text="10000"
FontSize="18" FontSize="18"
Text="{Binding ReceivedEventCount}" /> Text="{Binding ReceivedEventCount}" />
</StackPanel> </StackPanel>
<StackPanel Margin="10,0,0,0" Orientation="Horizontal"> <StackPanel Margin="10,0,0,0" Orientation="Horizontal">
<TextBlock VerticalAlignment="Center" <TextBlock
Text="预警数量:" VerticalAlignment="Center"
FontSize="14" /> FontSize="14"
<TextBlock VerticalAlignment="Center" Text="预警数量:" />
<TextBlock
VerticalAlignment="Center"
d:Text="10000" d:Text="10000"
FontSize="18" FontSize="18"
Text="{Binding AlarmedEventCount}" /> Text="{Binding AlarmedEventCount}" />
</StackPanel> </StackPanel>
<StackPanel Margin="10,0,0,0" Orientation="Horizontal">
<TextBlock
VerticalAlignment="Center"
FontSize="14"
Text="数据时长:" />
<TextBlock
VerticalAlignment="Center"
d:Text="24小时"
FontSize="14"
Text="{Binding Path=(comm:GlobalConfig.DataLookbackHours), StringFormat={}{0:0.##}小时}" />
</StackPanel>
</StackPanel> </StackPanel>
<Button Grid.Column="1" <Button
Grid.Column="1"
Margin="0,0,5,0" Margin="0,0,5,0"
HorizontalAlignment="Right" HorizontalAlignment="Right"
Content="设置" Content="设置"
@ -211,17 +245,20 @@
<!--<ToggleButton Grid.Row="1" <!--<ToggleButton Grid.Row="1"
Grid.Column="1" Grid.Column="1"
Width="80" />--> Width="80" />-->
<StackPanel Grid.Row="1" <StackPanel
Grid.Row="1"
Grid.Column="1" Grid.Column="1"
HorizontalAlignment="Center" Margin="0,0,20,0"
HorizontalAlignment="Right"
Orientation="Horizontal"> Orientation="Horizontal">
<!--<TextBlock VerticalAlignment="Center" <!--<TextBlock VerticalAlignment="Center"
Text="运行状态:" />--> Text="运行状态:" />-->
<ToggleButton Margin="10,0,0,0" <ToggleButton
Margin="10,0,0,0"
HorizontalAlignment="Center" HorizontalAlignment="Center"
VerticalAlignment="Center" VerticalAlignment="Center"
IsChecked="{Binding Path=(comm:GlobalData.IsRunning), Mode=TwoWay}"
Command="{Binding StartMonitoringCommand}" Command="{Binding StartMonitoringCommand}"
IsChecked="{Binding Path=(comm:GlobalData.IsRunning), Mode=TwoWay}"
Template="{StaticResource StateButtonTemplate}"> Template="{StaticResource StateButtonTemplate}">
<ToggleButton.Effect> <ToggleButton.Effect>
<BlurEffect Radius="1" /> <BlurEffect Radius="1" />

@ -1,13 +1,17 @@
<prism:PrismApplication x:Class="Txgy.EWS.Client.Start.App" <prism:PrismApplication
x:Class="Txgy.EWS.Client.Start.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Txgy.EWS.Client.Start" xmlns:local="clr-namespace:Txgy.EWS.Client.Start"
xmlns:prism="http://prismlibrary.com/" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"> xmlns:prism="http://prismlibrary.com/">
<Application.Resources> <Application.Resources>
<ResourceDictionary> <ResourceDictionary>
<ResourceDictionary.MergedDictionaries> <ResourceDictionary.MergedDictionaries>
<materialDesign:BundledTheme BaseTheme="Dark" PrimaryColor="DeepPurple" SecondaryColor="Lime" /> <materialDesign:BundledTheme
BaseTheme="Dark"
PrimaryColor="DeepPurple"
SecondaryColor="Lime" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" /> <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" />
<ResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/SkinDefault.xaml" /> <ResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/SkinDefault.xaml" />
<ResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/Theme.xaml" /> <ResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/Theme.xaml" />

@ -62,8 +62,8 @@ namespace Txgy.EWS.Client.Start
{ {
var config = BusinessConfigManager.Current; var config = BusinessConfigManager.Current;
GlobalConfig.InitializeRuntimeSettings(config.Runtime); GlobalConfig.InitializeRuntimeSettings(config.Runtime);
Debug.WriteLine(GlobalConfig.LoadDataTimeLenMins); //Debug.WriteLine(GlobalConfig.LoadDataTimeLenMins);
Debug.WriteLine(GlobalConfig.DataCacheTimeLenMins); //Debug.WriteLine(GlobalConfig.DataCacheTimeLenMins);
return Container.Resolve<MainWindow>(); return Container.Resolve<MainWindow>();
} }
protected override void InitializeShell(Window shell) protected override void InitializeShell(Window shell)

@ -139,7 +139,7 @@
<Grid> <Grid>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition /> <ColumnDefinition />
<ColumnDefinition Width="160" /> <!--<ColumnDefinition Width="160" />-->
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<!--#region 标题栏--> <!--#region 标题栏-->
<ContentControl x:Name="ContentTitle" prism:RegionManager.RegionName="TitleRegion" /> <ContentControl x:Name="ContentTitle" prism:RegionManager.RegionName="TitleRegion" />

@ -20,8 +20,7 @@
"isDesign": false, "isDesign": false,
"isRealtime": true, "isRealtime": true,
"refreshInterval": 10, "refreshInterval": 10,
"eventShowTotalSeconds": 86400, "dataLookbackHours": 6,
"loadDataTimeLenMins": 720,
"dataCacheTimeLenMins": 720 "dataCacheTimeLenMins": 720
}, },
"database": { "database": {

@ -21,6 +21,7 @@ namespace Txgy.EWS.Client.SysModule
{ {
containerRegistry.RegisterForNavigation<FileUploadView>(); containerRegistry.RegisterForNavigation<FileUploadView>();
containerRegistry.RegisterForNavigation<MenuManagementView>(); containerRegistry.RegisterForNavigation<MenuManagementView>();
containerRegistry.RegisterForNavigation<SystemSettingsView>();
containerRegistry.RegisterDialog<AddFileDialog>(); containerRegistry.RegisterDialog<AddFileDialog>();
containerRegistry.RegisterDialog<AddMenuDialog>(); containerRegistry.RegisterDialog<AddMenuDialog>();

@ -92,6 +92,7 @@
<Compile Include="ViewModels\AddMenuDialogViewModel.cs" /> <Compile Include="ViewModels\AddMenuDialogViewModel.cs" />
<Compile Include="ViewModels\FileUploadViewModel.cs" /> <Compile Include="ViewModels\FileUploadViewModel.cs" />
<Compile Include="ViewModels\MenuManagementViewModel.cs" /> <Compile Include="ViewModels\MenuManagementViewModel.cs" />
<Compile Include="ViewModels\SystemSettingsViewModel.cs" />
<Compile Include="Views\AddFileDialog.xaml.cs"> <Compile Include="Views\AddFileDialog.xaml.cs">
<DependentUpon>AddFileDialog.xaml</DependentUpon> <DependentUpon>AddFileDialog.xaml</DependentUpon>
</Compile> </Compile>
@ -104,6 +105,9 @@
<Compile Include="Views\MenuManagementView.xaml.cs"> <Compile Include="Views\MenuManagementView.xaml.cs">
<DependentUpon>MenuManagementView.xaml</DependentUpon> <DependentUpon>MenuManagementView.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="Views\SystemSettingsView.xaml.cs">
<DependentUpon>SystemSettingsView.xaml</DependentUpon>
</Compile>
<EmbeddedResource Include="Properties\Resources.resx"> <EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator> <Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput> <LastGenOutput>Resources.Designer.cs</LastGenOutput>
@ -132,6 +136,10 @@
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</Page> </Page>
<Page Include="Views\SystemSettingsView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Txgy.Controls\Txgy.Controls.csproj"> <ProjectReference Include="..\Txgy.Controls\Txgy.Controls.csproj">

@ -0,0 +1,337 @@
using Prism.Commands;
using Prism.Events;
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Windows.Input;
using System.Windows.Media;
using Txgy.EWS.Client.Common;
using Txgy.EWS.Client.Common.MessageEvents;
namespace Txgy.EWS.Client.SysModule.ViewModels
{
public class SystemSettingsViewModel : BindableBase
{
private readonly IEventAggregator _eventAggregator;
private string _statusMessage;
private Brush _statusBrush = Brushes.Gray;
public SystemSettingsViewModel(IEventAggregator eventAggregator)
{
_eventAggregator = eventAggregator;
ReloadFromConfig();
}
public string ConfigPath => BusinessConfigManager.ConfigPath;
public string StatusMessage
{
get => _statusMessage;
set => SetProperty(ref _statusMessage, value);
}
public Brush StatusBrush
{
get => _statusBrush;
set => SetProperty(ref _statusBrush, value);
}
public string ApiDomain { get; set; }
public string AlarmSetting { get; set; }
public string AlarmLevelConfig { get; set; }
public string ReportEventLevelSetting { get; set; }
public string WorkAreaFilePath { get; set; }
public string StationsCsvFilePath { get; set; }
public string CadDwgFilePath { get; set; }
public string DwgJsonSetting { get; set; }
public string WavesMseedFilePath { get; set; }
public string WavesTxtFilePath { get; set; }
public string LocalSqLiteDb { get; set; }
public string DwgSettings { get; set; }
public string CadSettingsFileName { get; set; }
public bool IsDesign { get; set; }
public bool IsRealtime { get; set; }
public string RefreshInterval { get; set; }
public string DataLookbackHours { get; set; }
public string DataCacheTimeLenMins { get; set; }
public string TencentMySql { get; set; }
public string NasMySql { get; set; }
public string RealtimeResultTable { get; set; }
public string RealtimeWaveDataTable { get; set; }
public string RealtimeFocalmechanismTable { get; set; }
public string PostResultTable { get; set; }
public string PostWaveDataTable { get; set; }
public string PostFocalmechanismTable { get; set; }
public string CommpanyName { get; set; }
public string SystemNameCn { get; set; }
public string SystemNameEn { get; set; }
public string WorkAreaName { get; set; }
public string SystemShortName { get; set; }
public string DailyReportStartTime { get; set; }
public string DailyReportPlanOffsetX { get; set; }
public string DailyReportPlanOffsetY { get; set; }
public string BaseX { get; set; }
public string BaseY { get; set; }
public string BaseZ { get; set; }
public ICommand ReloadCommand => new DelegateCommand(ReloadFromConfig);
public ICommand ApplyCommand => new DelegateCommand(ApplyConfig);
private void ReloadFromConfig()
{
try
{
Load(BusinessConfigManager.Read());
SetStatus("已读取最新配置", Brushes.Gray);
}
catch (Exception ex)
{
SetStatus($"读取配置失败:{ex.Message}", Brushes.Red);
}
}
private void ApplyConfig()
{
try
{
var previousConfig = BusinessConfigManager.Current;
var config = BuildConfig();
var savedConfig = BusinessConfigManager.Save(config);
var shouldReloadWarningData = ShouldReloadWarningData(previousConfig, savedConfig);
GlobalConfig.ApplyBusinessConfig(savedConfig);
_eventAggregator.GetEvent<BusinessConfigChangedEvent>().Publish(savedConfig);
if (shouldReloadWarningData)
{
_eventAggregator.GetEvent<ReloadWarningDataEvent>().Publish();
}
Load(savedConfig);
SetStatus($"配置已应用:{DateTime.Now:HH:mm:ss}", Brushes.Green);
}
catch (Exception ex)
{
SetStatus($"应用失败:{ex.Message}", Brushes.Red);
}
}
private bool ShouldReloadWarningData(BusinessConfig previousConfig, BusinessConfig savedConfig)
{
if (previousConfig?.Runtime == null || savedConfig?.Runtime == null)
{
return false;
}
return previousConfig.Runtime.DataLookbackHours != savedConfig.Runtime.DataLookbackHours;
}
private void Load(BusinessConfig config)
{
ApiDomain = config.Endpoints.ApiDomain;
AlarmSetting = config.Paths.AlarmSetting;
AlarmLevelConfig = config.Paths.AlarmLevelConfig;
ReportEventLevelSetting = config.Paths.ReportEventLevelSetting;
WorkAreaFilePath = config.Paths.WorkAreaFilePath;
StationsCsvFilePath = config.Paths.StationsCsvFilePath;
CadDwgFilePath = config.Paths.CadDwgFilePath;
DwgJsonSetting = config.Paths.DwgJsonSetting;
WavesMseedFilePath = config.Paths.WavesMseedFilePath;
WavesTxtFilePath = config.Paths.WavesTxtFilePath;
LocalSqLiteDb = config.Paths.LocalSqLiteDb;
DwgSettings = config.Paths.DwgSettings;
CadSettingsFileName = config.Paths.CadSettingsFileName;
IsDesign = config.Runtime.IsDesign;
IsRealtime = config.Runtime.IsRealtime;
RefreshInterval = config.Runtime.RefreshInterval.ToString(CultureInfo.InvariantCulture);
DataLookbackHours = config.Runtime.DataLookbackHours.ToString("0.##", CultureInfo.InvariantCulture);
DataCacheTimeLenMins = config.Runtime.DataCacheTimeLenMins.ToString(CultureInfo.InvariantCulture);
TencentMySql = GetConnection(config, "TencetnMySQL");
NasMySql = GetConnection(config, "NasMySQL");
RealtimeResultTable = config.Database.Tables.RealtimeResultTable;
RealtimeWaveDataTable = config.Database.Tables.RealtimeWaveDataTable;
RealtimeFocalmechanismTable = config.Database.Tables.RealtimeFocalmechanismTable;
PostResultTable = config.Database.Tables.PostResultTable;
PostWaveDataTable = config.Database.Tables.PostWaveDataTable;
PostFocalmechanismTable = config.Database.Tables.PostFocalmechanismTable;
CommpanyName = config.Branding.CommpanyName;
SystemNameCn = config.Branding.SystemNameCn;
SystemNameEn = config.Branding.SystemNameEn;
WorkAreaName = config.Branding.WorkAreaName;
SystemShortName = config.Branding.SystemShortName;
DailyReportStartTime = config.Report.DailyReportStartTime;
DailyReportPlanOffsetX = config.Report.DailyReportPlanOffsetX.ToString(CultureInfo.InvariantCulture);
DailyReportPlanOffsetY = config.Report.DailyReportPlanOffsetY.ToString(CultureInfo.InvariantCulture);
BaseX = config.Coordinates.BaseX.ToString(CultureInfo.InvariantCulture);
BaseY = config.Coordinates.BaseY.ToString(CultureInfo.InvariantCulture);
BaseZ = config.Coordinates.BaseZ.ToString(CultureInfo.InvariantCulture);
RaiseAllSettingPropertiesChanged();
}
private BusinessConfig BuildConfig()
{
DateTime.Parse(Require(DailyReportStartTime, "日报起始时间"));
var dataLookbackHours = ParseDouble(DataLookbackHours, "数据回看时长");
DataCacheTimeLenMins = ((int)Math.Round(dataLookbackHours * 60.0)).ToString(CultureInfo.InvariantCulture);
return new BusinessConfig
{
Endpoints = new EndpointSettings
{
ApiDomain = Require(ApiDomain, "API 域名")
},
Paths = new PathSettings
{
AlarmSetting = Require(AlarmSetting, "报警配置"),
AlarmLevelConfig = Require(AlarmLevelConfig, "报警等级配置"),
ReportEventLevelSetting = Require(ReportEventLevelSetting, "报表事件分级"),
WorkAreaFilePath = Require(WorkAreaFilePath, "工区配置"),
StationsCsvFilePath = Require(StationsCsvFilePath, "台站 CSV"),
CadDwgFilePath = Require(CadDwgFilePath, "CAD DWG"),
DwgJsonSetting = Require(DwgJsonSetting, "DWG 图层配置"),
WavesMseedFilePath = Require(WavesMseedFilePath, "Mseed 缓存目录"),
WavesTxtFilePath = Require(WavesTxtFilePath, "Txt 缓存目录"),
LocalSqLiteDb = Require(LocalSqLiteDb, "本地 SQLite"),
DwgSettings = EmptyToNull(DwgSettings),
CadSettingsFileName = EmptyToNull(CadSettingsFileName)
},
Runtime = new RuntimeSettings
{
IsDesign = IsDesign,
IsRealtime = IsRealtime,
RefreshInterval = ParseInt(RefreshInterval, "刷新间隔"),
DataLookbackHours = dataLookbackHours,
DataCacheTimeLenMins = ParseInt(DataCacheTimeLenMins, "数据缓存时长")
},
Database = new DatabaseSettings
{
Connections = new Dictionary<string, string>
{
{ "TencetnMySQL", Require(TencentMySql, "腾讯 MySQL") },
{ "NasMySQL", Require(NasMySql, "NAS MySQL") }
},
Tables = new TableSettings
{
RealtimeResultTable = Require(RealtimeResultTable, "实时结果表"),
RealtimeWaveDataTable = Require(RealtimeWaveDataTable, "实时波形表"),
RealtimeFocalmechanismTable = Require(RealtimeFocalmechanismTable, "实时震源机制表"),
PostResultTable = Require(PostResultTable, "后处理结果表"),
PostWaveDataTable = Require(PostWaveDataTable, "后处理波形表"),
PostFocalmechanismTable = Require(PostFocalmechanismTable, "后处理震源机制表")
}
},
Branding = new BrandingSettings
{
CommpanyName = Require(CommpanyName, "公司名称"),
SystemNameCn = Require(SystemNameCn, "系统中文名"),
SystemNameEn = Require(SystemNameEn, "系统英文名"),
WorkAreaName = Require(WorkAreaName, "工区名称"),
SystemShortName = Require(SystemShortName, "系统简称")
},
Report = new ReportSettings
{
DailyReportStartTime = DailyReportStartTime.Trim(),
DailyReportPlanOffsetX = ParseDouble(DailyReportPlanOffsetX, "平面图横向偏移"),
DailyReportPlanOffsetY = ParseDouble(DailyReportPlanOffsetY, "平面图纵向偏移")
},
Coordinates = new CoordinateSettings
{
BaseX = ParseDouble(BaseX, "BaseX"),
BaseY = ParseDouble(BaseY, "BaseY"),
BaseZ = ParseDouble(BaseZ, "BaseZ")
}
};
}
private string GetConnection(BusinessConfig config, string name)
{
if (config.Database.Connections != null && config.Database.Connections.TryGetValue(name, out var value))
{
return value;
}
return string.Empty;
}
private string Require(string value, string name)
{
if (string.IsNullOrWhiteSpace(value))
{
throw new InvalidOperationException($"{name}不能为空");
}
return value.Trim();
}
private string EmptyToNull(string value)
{
return string.IsNullOrWhiteSpace(value) ? null : value.Trim();
}
private int ParseInt(string value, string name)
{
if (!int.TryParse(Require(value, name), NumberStyles.Integer, CultureInfo.InvariantCulture, out var result))
{
throw new InvalidOperationException($"{name}必须是整数");
}
return result;
}
private double ParseDouble(string value, string name)
{
if (!double.TryParse(Require(value, name), NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
{
throw new InvalidOperationException($"{name}必须是数字");
}
return result;
}
private void SetStatus(string message, Brush brush)
{
StatusMessage = message;
StatusBrush = brush;
}
private void RaiseAllSettingPropertiesChanged()
{
RaisePropertyChanged(nameof(ApiDomain));
RaisePropertyChanged(nameof(AlarmSetting));
RaisePropertyChanged(nameof(AlarmLevelConfig));
RaisePropertyChanged(nameof(ReportEventLevelSetting));
RaisePropertyChanged(nameof(WorkAreaFilePath));
RaisePropertyChanged(nameof(StationsCsvFilePath));
RaisePropertyChanged(nameof(CadDwgFilePath));
RaisePropertyChanged(nameof(DwgJsonSetting));
RaisePropertyChanged(nameof(WavesMseedFilePath));
RaisePropertyChanged(nameof(WavesTxtFilePath));
RaisePropertyChanged(nameof(LocalSqLiteDb));
RaisePropertyChanged(nameof(DwgSettings));
RaisePropertyChanged(nameof(CadSettingsFileName));
RaisePropertyChanged(nameof(IsDesign));
RaisePropertyChanged(nameof(IsRealtime));
RaisePropertyChanged(nameof(RefreshInterval));
RaisePropertyChanged(nameof(DataLookbackHours));
RaisePropertyChanged(nameof(DataCacheTimeLenMins));
RaisePropertyChanged(nameof(TencentMySql));
RaisePropertyChanged(nameof(NasMySql));
RaisePropertyChanged(nameof(RealtimeResultTable));
RaisePropertyChanged(nameof(RealtimeWaveDataTable));
RaisePropertyChanged(nameof(RealtimeFocalmechanismTable));
RaisePropertyChanged(nameof(PostResultTable));
RaisePropertyChanged(nameof(PostWaveDataTable));
RaisePropertyChanged(nameof(PostFocalmechanismTable));
RaisePropertyChanged(nameof(CommpanyName));
RaisePropertyChanged(nameof(SystemNameCn));
RaisePropertyChanged(nameof(SystemNameEn));
RaisePropertyChanged(nameof(WorkAreaName));
RaisePropertyChanged(nameof(SystemShortName));
RaisePropertyChanged(nameof(DailyReportStartTime));
RaisePropertyChanged(nameof(DailyReportPlanOffsetX));
RaisePropertyChanged(nameof(DailyReportPlanOffsetY));
RaisePropertyChanged(nameof(BaseX));
RaisePropertyChanged(nameof(BaseY));
RaisePropertyChanged(nameof(BaseZ));
}
}
}

@ -0,0 +1,262 @@
<UserControl x:Class="Txgy.EWS.Client.SysModule.Views.SystemSettingsView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"
mc:Ignorable="d"
d:DesignHeight="760"
d:DesignWidth="1100">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Txgy.EWS.Client.Assets;component/Styles/BaseResources.xaml"/>
<ResourceDictionary Source="/Txgy.EWS.Client.Assets;component/Styles/ButtonStyles.xaml"/>
<ResourceDictionary Source="/Txgy.EWS.Client.Assets;component/Styles/TextBoxStyle.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style x:Key="SettingGroupStyle" TargetType="GroupBox">
<Setter Property="Margin" Value="0,0,0,16"/>
<Setter Property="Padding" Value="14"/>
<Setter Property="BorderBrush" Value="#FFE6E8EC"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="FontSize" Value="14"/>
</Style>
<Style x:Key="SettingLabelStyle" TargetType="TextBlock">
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Foreground" Value="#666"/>
<Setter Property="Margin" Value="0,5"/>
</Style>
<Style x:Key="SettingTextBoxStyle" TargetType="TextBox" BasedOn="{StaticResource NormalTextBoxStyle}">
<Setter Property="Height" Value="32"/>
<Setter Property="Margin" Value="0,5"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
</Style>
<Style x:Key="SettingCheckBoxStyle" TargetType="CheckBox">
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Margin" Value="0,5"/>
</Style>
</ResourceDictionary>
</UserControl.Resources>
<Grid Margin="24">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<DockPanel Margin="0,0,0,16">
<StackPanel DockPanel.Dock="Left">
<TextBlock Text="系统设置" FontSize="24" FontWeight="Bold" Foreground="#333"/>
<TextBlock Text="{Binding ConfigPath}" Margin="0,6,0,0" Foreground="#888"/>
</StackPanel>
<TextBlock DockPanel.Dock="Right"
Text="{Binding StatusMessage}"
Foreground="{Binding StatusBrush}"
VerticalAlignment="Bottom"
TextWrapping="Wrap"
MaxWidth="420"/>
</DockPanel>
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto">
<StackPanel>
<GroupBox Header="接口" Style="{StaticResource SettingGroupStyle}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="170"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Text="API 域名" Style="{StaticResource SettingLabelStyle}"/>
<TextBox Grid.Column="1" Text="{Binding ApiDomain, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource SettingTextBoxStyle}"/>
</Grid>
</GroupBox>
<GroupBox Header="运行参数" Style="{StaticResource SettingGroupStyle}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="170"/>
<ColumnDefinition/>
<ColumnDefinition Width="170"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock Text="设计模式" Style="{StaticResource SettingLabelStyle}"/>
<CheckBox Grid.Column="1" IsChecked="{Binding IsDesign}" Style="{StaticResource SettingCheckBoxStyle}"/>
<TextBlock Grid.Column="2" Text="实时模式" Style="{StaticResource SettingLabelStyle}"/>
<CheckBox Grid.Column="3" IsChecked="{Binding IsRealtime}" Style="{StaticResource SettingCheckBoxStyle}"/>
<TextBlock Grid.Row="1" Text="刷新间隔(秒)" Style="{StaticResource SettingLabelStyle}"/>
<TextBox Grid.Row="1" Grid.Column="1" Text="{Binding RefreshInterval, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource SettingTextBoxStyle}"/>
<TextBlock Grid.Row="1" Grid.Column="2" Text="数据回看时长(小时)" Style="{StaticResource SettingLabelStyle}"/>
<TextBox Grid.Row="1" Grid.Column="3" Text="{Binding DataLookbackHours, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource SettingTextBoxStyle}"/>
<TextBlock Grid.Row="2" Grid.Column="2" Text="数据缓存时长(分钟)" Style="{StaticResource SettingLabelStyle}" Visibility="Collapsed"/>
<TextBox Grid.Row="2" Grid.Column="3" Text="{Binding DataCacheTimeLenMins, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource SettingTextBoxStyle}" Visibility="Collapsed"/>
</Grid>
</GroupBox>
<GroupBox Header="路径" Style="{StaticResource SettingGroupStyle}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="170"/>
<ColumnDefinition/>
<ColumnDefinition Width="170"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock Text="报警配置" Style="{StaticResource SettingLabelStyle}"/>
<TextBox Grid.Column="1" Text="{Binding AlarmSetting, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource SettingTextBoxStyle}"/>
<TextBlock Grid.Column="2" Text="报警等级配置" Style="{StaticResource SettingLabelStyle}"/>
<TextBox Grid.Column="3" Text="{Binding AlarmLevelConfig, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource SettingTextBoxStyle}"/>
<TextBlock Grid.Row="1" Text="报表事件分级" Style="{StaticResource SettingLabelStyle}"/>
<TextBox Grid.Row="1" Grid.Column="1" Text="{Binding ReportEventLevelSetting, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource SettingTextBoxStyle}"/>
<TextBlock Grid.Row="1" Grid.Column="2" Text="工区配置" Style="{StaticResource SettingLabelStyle}"/>
<TextBox Grid.Row="1" Grid.Column="3" Text="{Binding WorkAreaFilePath, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource SettingTextBoxStyle}"/>
<TextBlock Grid.Row="2" Text="台站 CSV" Style="{StaticResource SettingLabelStyle}"/>
<TextBox Grid.Row="2" Grid.Column="1" Text="{Binding StationsCsvFilePath, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource SettingTextBoxStyle}"/>
<TextBlock Grid.Row="2" Grid.Column="2" Text="CAD DWG" Style="{StaticResource SettingLabelStyle}"/>
<TextBox Grid.Row="2" Grid.Column="3" Text="{Binding CadDwgFilePath, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource SettingTextBoxStyle}"/>
<TextBlock Grid.Row="3" Text="DWG 图层配置" Style="{StaticResource SettingLabelStyle}"/>
<TextBox Grid.Row="3" Grid.Column="1" Text="{Binding DwgJsonSetting, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource SettingTextBoxStyle}"/>
<TextBlock Grid.Row="3" Grid.Column="2" Text="Mseed 缓存目录" Style="{StaticResource SettingLabelStyle}"/>
<TextBox Grid.Row="3" Grid.Column="3" Text="{Binding WavesMseedFilePath, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource SettingTextBoxStyle}"/>
<TextBlock Grid.Row="4" Text="Txt 缓存目录" Style="{StaticResource SettingLabelStyle}"/>
<TextBox Grid.Row="4" Grid.Column="1" Text="{Binding WavesTxtFilePath, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource SettingTextBoxStyle}"/>
<TextBlock Grid.Row="4" Grid.Column="2" Text="本地 SQLite" Style="{StaticResource SettingLabelStyle}"/>
<TextBox Grid.Row="4" Grid.Column="3" Text="{Binding LocalSqLiteDb, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource SettingTextBoxStyle}"/>
<TextBlock Grid.Row="5" Text="DWG 显示设置" Style="{StaticResource SettingLabelStyle}"/>
<TextBox Grid.Row="5" Grid.Column="1" Text="{Binding DwgSettings, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource SettingTextBoxStyle}"/>
<TextBlock Grid.Row="5" Grid.Column="2" Text="CAD 设置文件" Style="{StaticResource SettingLabelStyle}"/>
<TextBox Grid.Row="5" Grid.Column="3" Text="{Binding CadSettingsFileName, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource SettingTextBoxStyle}"/>
</Grid>
</GroupBox>
<GroupBox Header="数据库" Style="{StaticResource SettingGroupStyle}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="170"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock Text="腾讯 MySQL" Style="{StaticResource SettingLabelStyle}"/>
<TextBox Grid.Column="1" Text="{Binding TencentMySql, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource SettingTextBoxStyle}"/>
<TextBlock Grid.Row="1" Text="NAS MySQL" Style="{StaticResource SettingLabelStyle}"/>
<TextBox Grid.Row="1" Grid.Column="1" Text="{Binding NasMySql, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource SettingTextBoxStyle}"/>
<TextBlock Grid.Row="2" Text="实时结果表" Style="{StaticResource SettingLabelStyle}"/>
<TextBox Grid.Row="2" Grid.Column="1" Text="{Binding RealtimeResultTable, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource SettingTextBoxStyle}"/>
<TextBlock Grid.Row="3" Text="实时波形表" Style="{StaticResource SettingLabelStyle}"/>
<TextBox Grid.Row="3" Grid.Column="1" Text="{Binding RealtimeWaveDataTable, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource SettingTextBoxStyle}"/>
<TextBlock Grid.Row="4" Text="实时震源机制表" Style="{StaticResource SettingLabelStyle}"/>
<TextBox Grid.Row="4" Grid.Column="1" Text="{Binding RealtimeFocalmechanismTable, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource SettingTextBoxStyle}"/>
<TextBlock Grid.Row="5" Text="后处理结果表" Style="{StaticResource SettingLabelStyle}"/>
<TextBox Grid.Row="5" Grid.Column="1" Text="{Binding PostResultTable, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource SettingTextBoxStyle}"/>
<TextBlock Grid.Row="6" Text="后处理波形表" Style="{StaticResource SettingLabelStyle}"/>
<TextBox Grid.Row="6" Grid.Column="1" Text="{Binding PostWaveDataTable, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource SettingTextBoxStyle}"/>
<TextBlock Grid.Row="7" Text="后处理震源机制表" Style="{StaticResource SettingLabelStyle}"/>
<TextBox Grid.Row="7" Grid.Column="1" Text="{Binding PostFocalmechanismTable, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource SettingTextBoxStyle}"/>
</Grid>
</GroupBox>
<GroupBox Header="品牌与报表" Style="{StaticResource SettingGroupStyle}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="170"/>
<ColumnDefinition/>
<ColumnDefinition Width="170"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock Text="公司名称" Style="{StaticResource SettingLabelStyle}"/>
<TextBox Grid.Column="1" Text="{Binding CommpanyName, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource SettingTextBoxStyle}"/>
<TextBlock Grid.Column="2" Text="工区名称" Style="{StaticResource SettingLabelStyle}"/>
<TextBox Grid.Column="3" Text="{Binding WorkAreaName, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource SettingTextBoxStyle}"/>
<TextBlock Grid.Row="1" Text="系统中文名" Style="{StaticResource SettingLabelStyle}"/>
<TextBox Grid.Row="1" Grid.Column="1" Text="{Binding SystemNameCn, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource SettingTextBoxStyle}"/>
<TextBlock Grid.Row="1" Grid.Column="2" Text="系统英文名" Style="{StaticResource SettingLabelStyle}"/>
<TextBox Grid.Row="1" Grid.Column="3" Text="{Binding SystemNameEn, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource SettingTextBoxStyle}"/>
<TextBlock Grid.Row="2" Text="系统简称" Style="{StaticResource SettingLabelStyle}"/>
<TextBox Grid.Row="2" Grid.Column="1" Text="{Binding SystemShortName, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource SettingTextBoxStyle}"/>
<TextBlock Grid.Row="2" Grid.Column="2" Text="日报起始时间" Style="{StaticResource SettingLabelStyle}"/>
<TextBox Grid.Row="2" Grid.Column="3" Text="{Binding DailyReportStartTime, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource SettingTextBoxStyle}"/>
<TextBlock Grid.Row="3" Text="平面图横向偏移" Style="{StaticResource SettingLabelStyle}"/>
<TextBox Grid.Row="3" Grid.Column="1" Text="{Binding DailyReportPlanOffsetX, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource SettingTextBoxStyle}"/>
<TextBlock Grid.Row="3" Grid.Column="2" Text="平面图纵向偏移" Style="{StaticResource SettingLabelStyle}"/>
<TextBox Grid.Row="3" Grid.Column="3" Text="{Binding DailyReportPlanOffsetY, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource SettingTextBoxStyle}"/>
</Grid>
</GroupBox>
<GroupBox Header="坐标" Style="{StaticResource SettingGroupStyle}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="170"/>
<ColumnDefinition/>
<ColumnDefinition Width="170"/>
<ColumnDefinition/>
<ColumnDefinition Width="170"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Text="BaseX" Style="{StaticResource SettingLabelStyle}"/>
<TextBox Grid.Column="1" Text="{Binding BaseX, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource SettingTextBoxStyle}"/>
<TextBlock Grid.Column="2" Text="BaseY" Style="{StaticResource SettingLabelStyle}"/>
<TextBox Grid.Column="3" Text="{Binding BaseY, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource SettingTextBoxStyle}"/>
<TextBlock Grid.Column="4" Text="BaseZ" Style="{StaticResource SettingLabelStyle}"/>
<TextBox Grid.Column="5" Text="{Binding BaseZ, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource SettingTextBoxStyle}"/>
</Grid>
</GroupBox>
</StackPanel>
</ScrollViewer>
<DockPanel Grid.Row="2" Margin="0,16,0,0">
<Button Content="重新读取"
Width="100"
Height="34"
Margin="0,0,8,0"
Style="{StaticResource NormalButtonStyle}"
Background="#DDD"
Foreground="#666"
Command="{Binding ReloadCommand}"/>
<StackPanel DockPanel.Dock="Right" Orientation="Horizontal" HorizontalAlignment="Right">
<Button Content="应用"
Width="100"
Height="34"
Margin="8,0,0,0"
Style="{StaticResource NormalButtonStyle}"
Background="#FF0ABEFF"
Command="{Binding ApplyCommand}"/>
</StackPanel>
</DockPanel>
</Grid>
</UserControl>

@ -0,0 +1,12 @@
using System.Windows.Controls;
namespace Txgy.EWS.Client.SysModule.Views
{
public partial class SystemSettingsView : UserControl
{
public SystemSettingsView()
{
InitializeComponent();
}
}
}

@ -0,0 +1,452 @@
# Velopack + Supabase Storage 自动更新复用指南
本文档用于在桌面程序中复用“Velopack 生成安装包和更新包Supabase Storage 托管更新源”的自动更新流程。示例均使用占位符,不绑定任何具体项目。
## 方案概览
更新链路分为两部分:
1. 发布端使用 Velopack CLI 将程序发布目录打包成安装包、全量包、差分包和 `releases.win.json`
2. 上传端将这些产物放到 Supabase Storage 的公开桶目录中。
3. 客户端运行时只读取公开更新源 URL调用 Velopack 检查、下载并应用更新。
客户端不需要 Supabase key。Supabase key 只应出现在发布脚本、CI/CD 或受信任的维护机器中。
## Supabase 配置
### 1. 创建 Storage 桶
推荐使用一个专门存放发布包的公开 File bucket
| 配置项 | 推荐值 | 说明 |
| --- | --- | --- |
| Bucket name | `app-releases` | 可按组织统一命名 |
| Public bucket | `true` | 客户端需要匿名下载 `releases.win.json` 和安装包 |
| File size limit | 按安装包大小设置 | 例如 `512MB`、`1GB` 或更高 |
| Allowed MIME types | 留空或允许二进制 | Velopack 产物包含 `.exe`、`.nupkg`、`.json` 等 |
Dashboard 路径通常是:
```text
Supabase Dashboard -> Storage -> New bucket
```
也可以用 SQL 创建桶:
```sql
insert into storage.buckets (
id,
name,
public,
file_size_limit,
allowed_mime_types
)
values (
'app-releases',
'app-releases',
true,
1073741824,
null
)
on conflict (id) do update
set
public = excluded.public,
file_size_limit = excluded.file_size_limit,
allowed_mime_types = excluded.allowed_mime_types;
```
### 2. 目录规划
建议每个应用、平台和发布通道使用独立目录:
```text
app-releases/
my-app/
windows/
stable/
releases.win.json
RELEASES
MyApp-win-Setup.exe
MyApp-1.2.3-full.nupkg
MyApp-1.2.3-delta.nupkg
beta/
releases.win.json
...
```
对应的 Velopack 更新源根地址为:
```text
https://<project-ref>.supabase.co/storage/v1/object/public/app-releases/my-app/windows/stable
```
Velopack 会在该根地址下读取 `releases.win.json`,所以不要把 `releases.win.json` 再放到额外子目录里。
### 3. 权限策略
推荐做法:
- 桶设为 public只开放匿名读取。
- 发布上传使用 `service_role` key并且只在 CI/CD 或维护机器环境变量中保存。
- 不给 `anon` 角色配置 `INSERT`、`UPDATE`、`DELETE` 权限。
- 不在客户端配置、日志、提交信息或文档中写入真实 key。
Supabase 的 public bucket 只代表对象可以通过公开 URL 读取;上传、覆盖、删除仍受访问控制影响。使用 `service_role` key 上传时会绕过 RLS适合发布流程。
如果必须用非 service role 的登录用户上传,需要在 `storage.objects` 上创建受限策略。下面示例只允许已登录用户写入指定目录,实际项目应再结合用户、角色或后端校验收紧权限:
```sql
create policy "release upload insert"
on storage.objects
for insert
to authenticated
with check (
bucket_id = 'app-releases'
and (storage.foldername(name))[1] = 'my-app'
);
create policy "release upload select"
on storage.objects
for select
to authenticated
using (
bucket_id = 'app-releases'
and (storage.foldername(name))[1] = 'my-app'
);
create policy "release upload update"
on storage.objects
for update
to authenticated
using (
bucket_id = 'app-releases'
and (storage.foldername(name))[1] = 'my-app'
)
with check (
bucket_id = 'app-releases'
and (storage.foldername(name))[1] = 'my-app'
);
```
覆盖已有文件需要 `SELECT``UPDATE` 权限。发布流程更推荐使用 service role而不是给普通客户端发放写权限。
## 应用配置文件
建议在应用中放一个独立配置文件,例如 `Config/update_config.json`
```json
{
"enable_auto_update": true,
"update_server_type": "supabase",
"update_server_url": "https://<project-ref>.supabase.co/storage/v1/object/public/app-releases/my-app/windows/stable",
"update_check_interval_hours": 24,
"silent_install": false,
"supabase": {
"project_url": "https://<project-ref>.supabase.co",
"bucket_name": "app-releases",
"directory": "my-app/windows/stable"
}
}
```
字段说明:
| 字段 | 用途 |
| --- | --- |
| `enable_auto_update` | 是否启用自动更新 |
| `update_server_type` | 可固定为 `supabase`,用于程序内部区分更新源 |
| `update_server_url` | 客户端 Velopack 更新源根地址 |
| `update_check_interval_hours` | 自动检查间隔;手动检查可忽略该间隔 |
| `silent_install` | 是否下载后延迟到下次启动自动应用 |
| `supabase.project_url` | 发布脚本上传时使用的 Supabase 项目 URL |
| `supabase.bucket_name` | 发布包所在 bucket |
| `supabase.directory` | bucket 内目录 |
`supabase` 节只给发布脚本使用。客户端运行时检查更新只需要 `update_server_url`
## 客户端集成
### 1. 安装 NuGet 包
```powershell
dotnet add <YourApp.csproj> package Velopack
```
### 2. 在程序入口尽早初始化
Velopack 初始化应尽量放在应用启动最早位置:
```csharp
using Velopack;
internal static class Program
{
[STAThread]
public static void Main(string[] args)
{
VelopackApp.Build()
.SetArgs(args)
.SetAutoApplyOnStartup(true)
.Run();
StartApplication(args);
}
}
```
`SetAutoApplyOnStartup(true)` 用于在下次启动时自动应用已下载但尚未安装的更新。
### 3. 检查、下载并应用更新
下面是最小可复用逻辑:
```csharp
using Velopack;
public sealed class AppUpdateService
{
private readonly string _updateServerUrl;
public AppUpdateService(string updateServerUrl)
{
_updateServerUrl = updateServerUrl;
}
public async Task<bool> CheckDownloadAndRestartAsync(
IProgress<int>? progress = null,
CancellationToken cancellationToken = default)
{
var manager = new UpdateManager(_updateServerUrl);
if (!manager.IsInstalled)
{
return false;
}
var updateInfo = await manager.CheckForUpdatesAsync().ConfigureAwait(false);
if (updateInfo?.TargetFullRelease is null)
{
return false;
}
await manager.DownloadUpdatesAsync(
updateInfo,
value => progress?.Report(Math.Clamp(value, 0, 100)),
cancellationToken).ConfigureAwait(false);
manager.ApplyUpdatesAndRestart(updateInfo.TargetFullRelease);
return true;
}
}
```
建议在 UI 层:
- 启动后延迟 1 到 3 秒检查,避免影响首屏。
- 发现新版本后先提示用户,再下载并重启。
- 手动“检查更新”按钮忽略检查间隔。
- 开发环境或直接运行 `dotnet run` 时,`manager.IsInstalled` 通常为 `false`,应跳过更新检查。
## 打包发布
### 1. 安装 Velopack CLI
```powershell
dotnet tool install -g vpk
```
### 2. 提升版本号
更新项目文件中的版本号,确保新版本高于线上版本:
```xml
<Version>1.2.3</Version>
```
### 3. 发布应用目录
```powershell
dotnet publish .\src\MyApp\MyApp.csproj `
-c Release `
-r win-x64 `
--self-contained false `
-o .\artifacts\publish\my-app
```
如果目标机器不保证安装 .NET Runtime可以改用 self-contained 发布,或按 Velopack 文档为安装包配置所需 framework。
### 4. 生成 Velopack 包
```powershell
vpk pack `
--packId MyCompany.MyApp `
--packVersion 1.2.3 `
--packDir .\artifacts\publish\my-app `
--mainExe MyApp.exe `
--packTitle "My App" `
--packAuthors "MyCompany" `
--outputDir .\artifacts\releases\my-app
```
输出目录应至少包含:
```text
MyApp-win-Setup.exe
MyCompany.MyApp-1.2.3-full.nupkg
MyCompany.MyApp-1.2.3-delta.nupkg
releases.win.json
RELEASES
```
首次发布可能没有 delta 包;从第二次发布开始应包含 delta 包。
## 上传到 Supabase Storage
发布脚本应读取配置文件中的 `supabase.project_url`、`supabase.bucket_name` 和 `supabase.directory`,并从环境变量读取服务端 key
```powershell
$env:SUPABASE_SERVICE_ROLE_KEY = "<service-role-key>"
```
通用上传脚本示例:
```powershell
param(
[Parameter(Mandatory = $true)]
[string]$ConfigPath,
[Parameter(Mandatory = $true)]
[string]$ReleasePath,
[string]$ServiceRoleKey = $env:SUPABASE_SERVICE_ROLE_KEY
)
$ErrorActionPreference = "Stop"
function Join-UrlPath {
param(
[string]$Left,
[string]$Right
)
if ([string]::IsNullOrWhiteSpace($Left)) {
return $Right
}
if ([string]::IsNullOrWhiteSpace($Right)) {
return $Left.TrimEnd("/")
}
return $Left.TrimEnd("/") + "/" + $Right.TrimStart("/")
}
if ([string]::IsNullOrWhiteSpace($ServiceRoleKey)) {
throw "SUPABASE_SERVICE_ROLE_KEY is empty."
}
$config = Get-Content -Encoding UTF8 $ConfigPath -Raw | ConvertFrom-Json
$baseUrl = $config.supabase.project_url.TrimEnd("/")
$bucketName = $config.supabase.bucket_name
$directory = $config.supabase.directory
if ([string]::IsNullOrWhiteSpace($baseUrl) -or
[string]::IsNullOrWhiteSpace($bucketName) -or
[string]::IsNullOrWhiteSpace($directory)) {
throw "Supabase project_url, bucket_name, or directory is missing."
}
$files = Get-ChildItem -Path $ReleasePath -File | Sort-Object Name
if (-not $files) {
throw "No release files were found."
}
$headers = @{
"apikey" = $ServiceRoleKey
"Authorization" = "Bearer $ServiceRoleKey"
}
foreach ($file in $files) {
$objectPath = Join-UrlPath $directory $file.Name
$uploadUrl = Join-UrlPath "$baseUrl/storage/v1/object/$bucketName" $objectPath
$uploadHeaders = $headers.Clone()
$uploadHeaders["Content-Type"] = "application/octet-stream"
$uploadHeaders["x-upsert"] = "true"
Invoke-RestMethod `
-Uri $uploadUrl `
-Method Post `
-Headers $uploadHeaders `
-InFile $file.FullName
}
$publicBaseUrl = Join-UrlPath "$baseUrl/storage/v1/object/public/$bucketName" $directory
Write-Host "Public feed root: $publicBaseUrl"
Write-Host "Velopack feed: $(Join-UrlPath $publicBaseUrl 'releases.win.json')"
```
上传命令:
```powershell
.\UploadReleaseToSupabase.ps1 `
-ConfigPath .\Config\update_config.json `
-ReleasePath .\artifacts\releases\my-app
```
## 发布后验证
### 1. 验证 feed 可访问
```powershell
$feedUrl = "https://<project-ref>.supabase.co/storage/v1/object/public/app-releases/my-app/windows/stable/releases.win.json"
$feed = Invoke-RestMethod -Uri $feedUrl -Method Get
$feed.Assets | Sort-Object {[version]$_.Version} -Descending | Select-Object -First 5 PackageId,Version,Type,FileName,Size
```
确认:
- 最新版本等于本次发布版本。
- 最新版本至少有 `Full` 资产。
- 非首次发布时应有 `Delta` 资产。
### 2. 验证安装包 URL
```powershell
curl.exe -I "https://<project-ref>.supabase.co/storage/v1/object/public/app-releases/my-app/windows/stable/MyApp-win-Setup.exe"
```
期望结果:
```text
HTTP/1.1 200 OK
```
### 3. 验证客户端更新
建议用两个版本验证:
1. 安装旧版本。
2. 上传新版本发布包。
3. 启动旧版本并触发检查更新。
4. 确认能发现新版本、下载进度正常、重启后版本号变为新版本。
## 复用检查清单
- Supabase Storage 已创建 public bucket。
- 更新包目录规划稳定,不同应用和通道互不覆盖。
- 客户端配置的 `update_server_url` 指向包含 `releases.win.json` 的目录。
- 发布脚本只在受信环境使用 `SUPABASE_SERVICE_ROLE_KEY`
- 客户端没有保存 Supabase key。
- 每次发布前提高应用版本号。
- `vpk pack` 输出包含 `releases.win.json`、`Setup.exe` 和 `.nupkg`
- 上传后 `releases.win.json` 可通过公开 URL 访问。
- 安装包 URL 返回 `200 OK`
- 至少用旧版本安装包做一次真实升级测试。
## 参考文档
- [Velopack C# Getting Started](https://docs.velopack.io/getting-started/csharp)
- [Velopack Integrating Overview](https://docs.velopack.io/integrating/overview)
- [Supabase Storage Buckets](https://supabase.com/docs/guides/storage/buckets/fundamentals)
- [Supabase Creating Buckets](https://supabase.com/docs/guides/storage/buckets/creating-buckets)
- [Supabase Storage Access Control](https://supabase.com/docs/guides/storage/security/access-control)
- [Supabase Standard Uploads](https://supabase.com/docs/guides/storage/uploads/standard-uploads)
Loading…
Cancel
Save