2010-10-07 81 views
1

我想向用戶強調任何已被修改的內容,以便他們知道他們已經改變了什麼,或者在後臺爲他們改變了編程方式。如何更改屬性更改時任何控件的外觀?

我想使用樣式將這個邏輯應用到我的所有控件,但我不知道如何。我知道我需要創建一個觸發器,但不知道要準確觸發什麼,或者如何獲取綁定屬性的任何更改,以便知道它是否已更改。

謝謝。

回答

-1

我會recomed唸叨稱爲INotifyPropertyChanged的

當你是一類幀你不再在UI線程因此,你應該使用誰是assoicated與UI線程看看調度員在另一件事的設計模式這

dispatcher on msdn

假設您想要打印新的電路板,你應該做它像這樣

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> 

你有一個按鈕,一分鐘,所以當按下按鈕,它會改變它的內容可見。

2

也許是最好的辦法涉及編寫一個包裝類爲你的價值觀實現INotifyPropertyChanged暴露了一個讀/寫objectValue屬性和布爾ValueHasChanged屬性。那麼你可以做變更跟蹤很容易在Value二傳手:

if (!value.Equals(_Value)) 
{ 
    _Value = value; 
    ValueHasChanged=true; 
    OnPropertyChanged("Value"); 
} 

而不是你的視圖模型類暴露stringDateTime性質的,它應該公開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"

2

我仍然得到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>