我想向用戶強調任何已被修改的內容,以便他們知道他們已經改變了什麼,或者在後臺爲他們改變了編程方式。如何更改屬性更改時任何控件的外觀?
我想使用樣式將這個邏輯應用到我的所有控件,但我不知道如何。我知道我需要創建一個觸發器,但不知道要準確觸發什麼,或者如何獲取綁定屬性的任何更改,以便知道它是否已更改。
謝謝。
我想向用戶強調任何已被修改的內容,以便他們知道他們已經改變了什麼,或者在後臺爲他們改變了編程方式。如何更改屬性更改時任何控件的外觀?
我想使用樣式將這個邏輯應用到我的所有控件,但我不知道如何。我知道我需要創建一個觸發器,但不知道要準確觸發什麼,或者如何獲取綁定屬性的任何更改,以便知道它是否已更改。
謝謝。
我會recomed唸叨稱爲INotifyPropertyChanged的
當你是一類幀你不再在UI線程因此,你應該使用誰是assoicated與UI線程看看調度員在另一件事的設計模式這
假設您想要打印新的電路板,你應該做它像這樣
printDelgate paintControlDelgate =() => paintControl();
m_CurrentDispatcher.Invoke(paintControlDelgate);
讓我們假設在你的代碼
<ControlTemplate x:Key="StarTemplate" TargetType="{x:Type Button}">
<Grid>
<ed:RegularPolygon Visibility="Collapsed" Name="star1" Fill="{Binding Path=ButtonColor}"
InnerRadius="0.47211" Margin="20.5,16,15.5,8" PointCount="5" Stroke="Black"
StrokeThickness="2" Height="40" Width="40"/>
<ed:RegularPolygon Name="star2" Fill="Black" Visibility="Visible" InnerRadius="0.47211" Margin="20.5,16,15.5,8"
PointCount="5" Stroke="Black" StrokeThickness="6" Height="40" Width="40"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="star1" Property="Visibility" Value="Visible"/>
<Setter TargetName="star2" Property="Visibility" Value="Collapsed"/>
</Trigger>
你有一個按鈕,一分鐘,所以當按下按鈕,它會改變它的內容可見。
也許是最好的辦法涉及編寫一個包裝類爲你的價值觀實現INotifyPropertyChanged
暴露了一個讀/寫object
型Value
屬性和布爾ValueHasChanged
屬性。那麼你可以做變更跟蹤很容易在Value
二傳手:
if (!value.Equals(_Value))
{
_Value = value;
ValueHasChanged=true;
OnPropertyChanged("Value");
}
而不是你的視圖模型類暴露string
或DateTime
性質的,它應該公開ValueWrapper
性質包裹其內部字段,例如:
private string SomeStringField;
private ValueWrapper _SomeStringProperty;
public ValueWrapper SomeStringProperty
{
get
{
return (_SomeStringProperty == null)
? _SomeStringProperty = new ValueWrapper(SomeStringField)
: _SomeStringProperty;
}
}
然後你就可以建立像一個風格:
<Style x:Key="ShowChangedValue">
<Setter Property="Background" Value="White"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ValueHasChanged}" Value="True">
<Setter Property="Background" Value="AliceBlue"/>
</DataTrigger>
</Style.Triggers>
</Style>
,並用它喜歡:
<TextBox DataContext="{Binding SomeStringProperty}"
Text="{Binding Value, Mode=TwoWay}"
Style="{StaticResource ShowChangedValue}"/>
大約有一些這方面的煩事,喜歡的事實,改變你的主視圖模型類中的屬性值,你現在必須使用SomeStringProperty.Value = "foo"
而不是SomeStringProperty = "foo"
。
我仍然得到WPF的縈繞,所以可能有更好的方法,但這是我認爲可以工作。
創建ValueTracker
類,這個類提供了以下3個附加依賴屬性
TrackProperty - 這將是應跟蹤控制的財產
默認值 - 這是值被認爲是默認值,否則會觸發Style觸發器。
IsDefaultValue - 這將指示當前值是否與默認值匹配,此屬性將用於觸發器測試。
這是一個快速測試,它不是完美的,但我相信有點tweeking會讓事情變好,當然有更多WPF經驗的人可以改進這個想法。
using System;
using System.Windows;
using System.ComponentModel;
namespace WpfApplication1
{
public static class ValueTracker
{
// Attached dependency property for DefaultValue
public static object GetDefaultValue(DependencyObject obj)
{
return (object)obj.GetValue(DefaultValueProperty);
}
public static void SetDefaultValue(DependencyObject obj, object value)
{
obj.SetValue(DefaultValueProperty, value);
}
public static readonly DependencyProperty DefaultValueProperty =
DependencyProperty.RegisterAttached("DefaultValue",
typeof(object), typeof(ValueTracker), new UIPropertyMetadata(0));
// Attached dependency property for IsDefaultValue
public static bool GetIsDefaultValue(DependencyObject obj)
{
return (bool)obj.GetValue(IsDefaultValueProperty);
}
private static void SetIsDefaultValue(DependencyObject obj, bool value)
{
obj.SetValue(IsDefaultValueProperty, value);
}
public static readonly DependencyProperty IsDefaultValueProperty =
DependencyProperty.RegisterAttached("IsDefaultValue",
typeof(bool), typeof(ValueTracker), new UIPropertyMetadata(false));
// Attached dependency property for TrackedProperty
public static DependencyProperty GetTrackProperty(DependencyObject obj)
{
return (DependencyProperty)obj.GetValue(TrackPropertyProperty);
}
public static void SetTrackProperty(DependencyObject obj, DependencyProperty value)
{
obj.SetValue(TrackPropertyProperty, value);
}
public static readonly DependencyProperty TrackPropertyProperty =
DependencyProperty.RegisterAttached("TrackProperty",
typeof(DependencyProperty), typeof(ValueTracker),
new UIPropertyMetadata(TrackPropertyChanged));
public static void TrackPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
DependencyProperty oldProperty = e.OldValue as DependencyProperty;
if (oldProperty != null)
{
DependencyPropertyDescriptor dpd =
DependencyPropertyDescriptor.FromProperty(oldProperty, typeof(UIElement));
if (dpd != null)
{
dpd.RemoveValueChanged(d, TrackedPropertyValueChanged);
}
}
DependencyProperty newProperty = e.NewValue as DependencyProperty;
if (newProperty != null)
{
DependencyPropertyDescriptor dpd =
DependencyPropertyDescriptor.FromProperty(newProperty, typeof(UIElement));
if (dpd != null)
{
dpd.AddValueChanged(d, TrackedPropertyValueChanged);
}
}
}
private static void TrackedPropertyValueChanged(object sender, EventArgs e)
{
DependencyObject o = sender as DependencyObject;
if (o != null)
{
object defaultValue = Convert.ChangeType(GetDefaultValue(o), GetTrackProperty(o).PropertyType);
SetIsDefaultValue(o, Object.Equals(o.GetValue(GetTrackProperty(o)), defaultValue));
}
}
}
}
以上可以使用如下。
1-創建觸發對ValueTracker.IsDefaultValue
2 - 對於您要跟蹤每個控件的樣式,你附加的樣式和設置ValueTracker.DefaultValue並設置應使用跟蹤屬性ValueTracker.TrackProperty。
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:r="clr-namespace:WpfApplication1"
mc:Ignorable="d" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication1"
Title="MainWindow"
d:DesignHeight="221" d:DesignWidth="287"
Width="250" Height="250">
<StackPanel Loaded="StackPanel_Loaded" >
<StackPanel.Resources>
<Style TargetType="{x:Type Control}" x:Key="trackChanges">
<Style.Triggers>
<Trigger Property="local:ValueTracker.IsDefaultValue" Value="false">
<Setter Property="FontWeight" Value="Bold" />
</Trigger>
</Style.Triggers>
</Style>
</StackPanel.Resources>
<TextBox Name="textbox1" Width="100" Height="23"
local:ValueTracker.DefaultValue="Help"
local:ValueTracker.TrackProperty="TextBox.Text"
Style="{StaticResource ResourceKey=trackChanges}" />
<ComboBox Name="combobox1"
SelectedIndex="2"
local:ValueTracker.DefaultValue="2"
local:ValueTracker.TrackProperty="ComboBox.SelectedIndex"
Style="{StaticResource ResourceKey=trackChanges}">
<ComboBox.Items>
<ComboBoxItem>Item 1</ComboBoxItem>
<ComboBoxItem>Item 2</ComboBoxItem>
<ComboBoxItem>Item 3</ComboBoxItem>
<ComboBoxItem>Item 4</ComboBoxItem>
</ComboBox.Items>
</ComboBox>
</StackPanel>
</Window>