![](/img/trans.png)
[英]C#: Caliburn Micro: How do I control the properties of a WPF Button using data binding?
[英]How do I properly utilize datatriggers and setters when using dependency properties in C# WPF?
我正在嘗試為 WPF HMI 應用程序創建通用狀態指示器顯示。 這些狀態指示器是用戶控件,其中兩個不同半徑的同心圓重疊。 我希望能夠根據我的StatusIndicator
class 的一些依賴屬性來更改路徑標記上“填充”屬性的顏色。 在實踐中,可以使用任意數量的這些指標。 這些指標的“狀態”由 class object、 DigitalIOAssignment
處理,它從給定 I/OZ2 組件的 Z9ED39E2EA931586B536A985A69EZ2 組件的 PLC 獲取其數據(componentID、isActive、isInterlocked 等)。 由於這些狀態指示器的數量是任意的,因此我創建了一個List <DigitalIOAssignment>
並將其傳遞給我的視圖模型。 這工作正常,我可以在我的視圖模型中看到我想要正確綁定的數據。
狀態指示燈編碼如下:
XAML:
<UserControl x:Class="HMI.UserControls.StatusIndicator"
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/"
xmlns:local="clr-namespace:HMI.UserControls"
xmlns:globals="clr-namespace:HMI.LogixPLCService.Globals;assembly=HMI.LogixPLCService"
mc:Ignorable="d"
d:DesignHeight="100" d:DesignWidth="100">
<Viewbox x:Name="ControlViewbox" Stretch="Uniform" Height="auto" Width="auto">
<Canvas x:Name="ControlCanvas" Width="100" Height="100">
<!-- Draw Secondary Indicator Body First -->
<Path x:Name="StatusIndicator_Body" Width="100" Height="100"
Canvas.Left="0" Canvas.Top="0" StrokeThickness="1"
StrokeMiterLimit="2.75" Stroke="Black">
<Path.Data>
<EllipseGeometry Center="50,50" RadiusX="50" RadiusY="50"/>
</Path.Data>
<Path.Style>
<Style TargetType="Path">
<Setter Property="Fill" Value="LightGray"/>
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:StatusIndicator}}, Path=isInterlockedProperty}"
Value="True">
<Setter Property="Fill" Value="Yellow"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Path.Style>
</Path>
<!-- Draw Foreground Indicator Body Second -->
<Path x:Name="StatusIndicator_Status" Width="100" Height="100"
Canvas.Left="0" Canvas.Top="0" StrokeThickness=".5"
StrokeMiterLimit="1" Stroke="Black">
<Path.Data>
<EllipseGeometry Center="50,50" RadiusX="30" RadiusY="30"/>
</Path.Data>
<Path.Style>
<Style TargetType="Path">
<Setter Property="Fill" Value="DarkGray"/>
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:StatusIndicator}}, Path=isActiveProperty}"
Value="True">
<Setter Property="Fill" Value="Lime"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Path.Style>
</Path>
</Canvas>
</Viewbox>
</UserControl>
代碼背后:
namespace HMI.UserControls
{
public partial class StatusIndicator : UserControl
{
/// <summary>
/// Interaction logic for StatusIndicator.xaml
///</summary>
public string StatusIndicatorName
{
get { return (string)GetValue(StatusIndicatorNameProperty); }
set { SetValue(StatusIndicatorNameProperty, value); }
}
public static readonly DependencyProperty StatusIndicatorNameProperty =
DependencyProperty.Register("StatusIndicatorName",
typeof(string), typeof(StatusIndicator), new PropertyMetadata(null));
public string ComponentID
{
get { return (string)GetValue(ComponentIDProperty); }
set { SetValue(ComponentIDProperty, value); }
}
public static readonly DependencyProperty ComponentIDProperty =
DependencyProperty.Register("ComponentID",
typeof(string), typeof(StatusIndicator), new PropertyMetadata(null));
public bool isActiveProperty
{
get { return (bool)GetValue(isActive); }
set { SetValue(isActive, value); }
}
public static readonly DependencyProperty isActive =
DependencyProperty.Register("isActiveProperty",
typeof(bool), typeof(StatusIndicator), new PropertyMetadata(false));
public bool isInterlockedProperty
{
get { return (bool)GetValue(isInterlocked); }
set { SetValue(isInterlocked, value); }
}
public static readonly DependencyProperty isInterlocked =
DependencyProperty.Register("isInterlockedProperty",
typeof(bool), typeof(StatusIndicator), new PropertyMetadata(false));
public StatusIndicator()
{
InitializeComponent();
}
}
}
在我的視圖的 xaml 中,我在設計器中創建每個狀態指示器並對其進行硬編碼x:Name
並將其分配給StatusIndicatorName
,因為我無法弄清楚如何在運行時將此 Name 值傳遞給代碼隱藏(任何提示將不勝感激。:)。 我想做的是:
StatusIndicatorName
屬性分配一個已知字符串UserControls:StatusIndicator.ComponentID
屬性綁定到DigitalIOAssignment.componentID
<DataTrigger>
,這將允許我在滿足觸發條件時引用相同的DigitalIOAssignment
object,並設置適當的標志(isActive、isInterlocked 等)這樣。 我希望,這個偽代碼代表我在我的視圖中嘗試做的 Xaml:<UserControls:StatusIndicator x:Name="DI_99VLV01"
StatusIndicatorName="{Binding ElementName=DI_99VLV01}"
Height="18" Width="18"
Margin="106,144,0,0"
HorizontalAlignment="Left" VerticalAlignment="Top"
ComponentID="{Binding privateDigitalInputAssignments/componentID}">
<DataTrigger Binding="{Binding Path=(UserControls:StatusIndicator.ComponentID)}"
Value="{Binding Path=(UserControls:StatusIndicator.StatusIndicatorName)}">
<Setter Property="UserControls:StatusIndicator.isActiveProperty"
Value="{Binding privateDigitalInputAssignments/isActive}"/>
<Setter Property="UserControls:StatusIndicator.isInterlockedProperty"
Value="{Binding privateDigitalInputAssignments/isInterlocked}"/>
</DataTrigger>
</UserControls:StatusIndicator>
顯然,這個實現是行不通的。 我不能對數據觸發器上的值使用綁定(我可能必須對我期望的組件 ID 進行硬編碼,因為無論如何我都對狀態指示器名稱進行了硬編碼),而且我似乎無法對我的依賴項屬性使用 setter。 我收到一個錯誤:
Cannot find the static member 'isActivePropertyProperty' [sic.] on the type 'StatusIndicator'.
有人可以給我一些見解如何解決我想要實現的這個問題嗎? 即使我需要重新開始並以不同的方式處理它? 謝謝!
我不是 100% 肯定我遵循你所追求的。 您有任意數量的DigitalIOAssignment
,它們保存在 VM 的列表中,並且您想在視圖中為它們中的每一個創建一個StatusIndicator
嗎?
執行此操作的常用方法是在視圖中使用ItemsControl
,並使用具有單個StatusIndicator
的DataTemplate
。 如果您將ItemsControl.ItemsSource
綁定到您的列表,wpf 將為列表中的每個項目應用模板,並且模板的DataContext
將是該項目,因此您可以進行直接綁定而無需觸發器。
就像是:
<ItemsControl ItemsSource="{Binding DigitalInputAssignments}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<UserControls:StatusIndicator Height="18" Width="18"
Margin="106,144,0,0"
HorizontalAlignment="Left" VerticalAlignment="Top"
StatusIndicatorName="{Binding Name}"
ComponentID="{Binding ComponentID}"
IsActive="{Binding IsActive}"
IsInterlocked="{Binding IsInterlocked}">
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.