2010-10-07 82 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>