我寫這篇文章是因為在 WPF 實作期間我在實作特定功能時遇到了困難。
對于資料模型緯度和經度(當前視窗中的位置)
MainViewModel 是我將其作為 observableCollection 進行管理。
在xaml中,顯示了每個模型串列的上、經度值,
以圖片的形式實作按鈕控制根據xaml中不斷更新的位置資訊進行移動的部分被屏蔽了,所以發這個。
另外,我想為方位角或每個分量顯示一條線,但我也想實作這一點,使線根據變化的值移動。
有沒有一種方法是通常用于這些變化的值,還是有一種方法主要在實踐中使用?在Winform的情況下,我使用了使用Graphics物件繪制線條的方法,但是如果有人知道如何通過在C# WPF中實時移動它并系結位置值來實時顯示它,我將不勝感激你可以分享它。
uj5u.com熱心網友回復:
在我之前的回答中,我演示了一種基于視圖模型中的屬性定位線條的方法。但是,這只能回答您的部分問題。
在下面的示例中,我將演示如何讓 ObservableCollection 具有將反映在螢屏上的位置,方法是將位置顯示為與它們的值對應的螢屏位置的文本。
首先,雖然 ObservableCollection 可以用作 Itemsource,但我們必須確保 Item 本身適合用作視圖模型:因此,您可以Position如下宣告一個類(使用“CommunityToolkit.Mvvm”):
using CommunityToolkit.Mvvm.ComponentModel;
namespace ViewModels;
public partial class Position : ObservableObject
{
[ObservableProperty]
private double _x;
[ObservableProperty]
private double _y;
public Position(double x = 0.0, double y = 0.0)
{
X = x;
Y = y;
}
}
現在您可以宣告一個MainViewModel包含ObservableCollection<Position>將用作 itemsource 的屬性。出于演示目的,位置的值將根據 a 不斷更改DispatchTimer:
using CommunityToolkit.Mvvm.ComponentModel;
using System;
using System.Collections.ObjectModel;
using System.Windows.Threading;
namespace PresentationLayer.ViewModels;
public class MainViewModel : ObservableObject
{
private DispatcherTimer _timer = new();
private Random _random = new();
// binding properties
public ObservableCollection<Position> TextPositions { get; private set; } = new();
public MainViewModel()
{
TextPositions.Add(new(10, 10));
TextPositions.Add(new(20, 100));
TextPositions.Add(new(50, 300));
_timer.Interval = TimeSpan.FromMilliseconds(100);
_timer.Tick = OntimerTick;
_timer.Start();
}
private void OntimerTick(object? sender, EventArgs e)
{
foreach (var item in TextPositions)
{
item.X = (item.X _random.Next(30)) % 600;
item.Y = (item.Y _random.Next(20)) % 350;
}
}
}
最后,這個 MainViewModel 可以用作 WPF 視窗的資料背景關系,顯示位置,ItemsControl使用資料模板構造要顯示的文本值。
使用ItemsControl.ItemContainerStyle系結專案位置的屬性來處理定位。
注意:為此,您需要指定ItemsPanelshould 的型別Canvas,因為 Location 的系結使用Canvas.Topand Canvas.Left。
MainWindow(使用MainViewModel實體作為資料背景關系):
<Canvas>
<ItemsControl ItemsSource="{Binding TextPositions}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Canvas.Top" Value="{Binding Y}"/>
<Setter Property="Canvas.Left" Value="{Binding X}"/>
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate >
<DataTemplate>
<Border BorderBrush="Blue" BorderThickness="1" CornerRadius="2" Background="LightSkyBlue">
<WrapPanel>
<TextBlock Text="{Binding X}" />
<TextBlock Text=", "/>
<TextBlock Text="{Binding Y}" />
</WrapPanel>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Canvas>
uj5u.com熱心網友回復:
對于控制元件或顯示元素的定位,您可以使用系結到 ViewModel 中的屬性。
在下面的示例中,我使用 Canvas 并將Canvas.Top線條的屬性系結到LinePosViewmodel 中的屬性。
另一種方法可能是系結 Rendertransform ......
<Canvas>
<Line X1="0" Y1="10" X2="500" Y2="10" Stroke="Blue" StrokeThickness="3" Canvas.Top="{Binding LinePos}" />
</Canvas>
和視圖模型:
public class MainViewModel : ObservableObject
{
private int _linePos;
private DispatcherTimer _timer = new();
// binding properties
public int LinePos
{
get => _linePos;
set => SetProperty(ref _linePos, value);
}
public MainViewModel()
{
_timer.Interval = TimeSpan.FromMilliseconds(10);
_timer.Tick = OnTimerTick;
_timer.Start();
}
private void OnTimerTick(object? sender, EventArgs e)
{
LinePos = (LinePos 1) % 500;
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/521348.html
標籤:C#wpfgdi
上一篇:異步/等待的競爭條件,如何解決
