2011-10-11 25 views
6

Tôi có bộ kích hoạt dữ liệu WPF được đặt để kích hoạt khi giá trị là đúng.WPF DataTrigger không kích hoạt nếu giá trị vẫn giữ nguyên

Tôi muốn trình kích hoạt này kích hoạt mọi lúc giá trị này được đặt thành true, ngay cả khi nó đúng. Thật không may có vẻ như chỉ cháy nếu giá trị được thay đổi từ đúng sang sai hoặc ngược lại. Mô hình dữ liệu cơ bản của tôi đang kích hoạt sự kiện PropertyChanged của INotifyPropertyChanged ngay cả khi giá trị được đặt thành true hai lần liên tiếp nhưng Trigger dường như không chọn điều này.

Có cách nào để thực hiện kích hoạt chạy bất kể giá trị bị ràng buộc có thay đổi không?

Một số bạn đã yêu cầu mã này ở đây. Điều thú vị cần lưu ý là người chuyển đổi sẽ được gọi mỗi lần. Vấn đề là cụ thể hơn để chạy một hình ảnh động.

Cập nhật Nếu tôi thay đổi mã của mình để đặt lại giá trị thành sai và sau đó quay lại true, nó sẽ kích hoạt hoạt ảnh. Rõ ràng đây không phải là lý tưởng và không làm cho mã tốt đẹp để đọc. Tôi hy vọng có một cách tốt hơn để làm điều này.

Bất kỳ trợ giúp nào được đánh giá cao.

đang WPF

<Grid> 
    <Grid.Resources>    
     <Storyboard x:Key="AnimateCellBlue"> 
      <ColorAnimation Storyboard.TargetProperty="Background.Color" From="Transparent" To="Blue" Duration="0:0:0.1" AutoReverse="True" RepeatBehavior="1x" /> 
     </Storyboard> 
    </Grid.Resources> 
    <TextBox Name="txtBox" Text="{Binding DataContext.DisplayText, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}">   
     <TextBox.Style> 
      <Style TargetType="TextBox"> 
       <Style.Triggers> 
        <DataTrigger Binding="{Binding DataContext.IsTrue, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" Value="True"> 
         <DataTrigger.EnterActions>               
          <BeginStoryboard Name="BidSizeUpStoryB" Storyboard="{StaticResource AnimateCellBlue}" /> 
         </DataTrigger.EnterActions> 
        </DataTrigger> 
       </Style.Triggers> 
      </Style> 
     </TextBox.Style> 
    </TextBox> 
</Grid> 

Mã Đằng sau: -

public partial class MainWindow : Window 
{ 
    private DataItem _dataItem; 
    private DispatcherTimer _dispatcherTimer; 

    public MainWindow() 
    { 
     InitializeComponent(); 

     _dataItem = new DataItem(); 
     _dataItem.DisplayText = "Testing"; 
     _dataItem.IsTrue = true; 

     this.DataContext = _dataItem; 

     _dispatcherTimer = new DispatcherTimer(TimeSpan.FromSeconds(1), DispatcherPriority.Normal, TimerCallbackHandler, Dispatcher); 

    } 

    private void TimerCallbackHandler(object s, EventArgs args) 
    { 
     Console.WriteLine("In Timer"); 
     _dataItem.IsTrue = true; 
     _dataItem.DisplayText = "Timer " + DateTime.Now.Ticks; 
    } 
} 

DataItem: -

public class DataItem : INotifyPropertyChanged 
{ 
    private bool _isTrue; 
    private string _displayText; 

    public bool IsTrue 
    { 
     get { return _isTrue; } 
     set 
     { 
      _isTrue = value; 
      NotifyPropertyChanged("IsTrue"); 
     } 
    } 

    public string DisplayText 
    { 
     get 
     { 
      return _displayText; 
     } 
     set 
     { 
      _displayText = value; 
      NotifyPropertyChanged("DisplayText"); 
     } 
    } 

    #region INotifyPropertyChanged Members 

    public event PropertyChangedEventHandler PropertyChanged; 

    #endregion 

    private void NotifyPropertyChanged(string info) 
    { 
     if (PropertyChanged != null) 
      PropertyChanged(this, new PropertyChangedEventArgs(info)); 
    } 
} 
+1

Hiển thị cho chúng tôi mã của thuộc tính và trình kích hoạt để chúng tôi không phải đoán. –

+0

Vui lòng xem mã mẫu của tôi ở trên. Các hình ảnh động sẽ chỉ cháy một lần. – user630190

Trả lời

1

Trigger sẽ được lửa không phụ thuộc vào các thiết lập giá trị. Bất cứ khi nào sự kiện PropertyChanged được nâng lên cho thuộc tính được gắn với trigger, trigger sẽ được gọi. Đây là mẫu mà tôi đã xác minh -

<TextBox> 
    <TextBox.Style> 
     <Style TargetType="TextBox"> 
      <Style.Triggers> 
      <DataTrigger Binding="{Binding DataContext.IsTrue, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}, 
                 Converter={StaticResource MyConverter}}" Value="True"> 
        <Setter Property="Background" Value="Red"/> 
      </DataTrigger> 
      </Style.Triggers> 
     </Style> 
    </TextBox.Style> 
</TextBox> 

Tôi đặt điểm ngắt trên trình chuyển đổi của mình và nó được gọi bất cứ khi nào tôi tăng sự kiện PropertyChanged cho thuộc tính IsTrue. Có msut là một số vấn đề khác trong mã của bạn. Bạn có thể vui lòng hiển thị bit của mã của bạn, nơi bạn đang phải đối mặt với vấn đề này?

+0

Vui lòng xem câu hỏi đã được thêm vào của tôi với mẫu mã. Đó là hoạt ảnh không bắn – user630190

0

Cập nhật: có vẻ như câu trả lời đầu tiên của tôi phụ thuộc vào ValueConverters của tôi. Vì vậy, tôi đã nghiên cứu thêm một chút và phát hiện ra ConditionalBehavior và PropertyChangedTrigger

Đây là một trong những thử nghiệm mà tôi đã thử nghiệm.

<UserControl 
      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:i="http://schemas.microsoft.com/expression/2010/interactivity" 
      xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" 
      x:Class="WpfControlLibrary1.UserControl1" 
      mc:Ignorable="d" 
      d:DesignHeight="300" d:DesignWidth="300"> 
    <UserControl.Triggers> 
     <EventTrigger RoutedEvent="FrameworkElement.Loaded"/> 
    </UserControl.Triggers> 
    <Grid> 
     <i:Interaction.Triggers> 
      <!--Use multiple PropertyChangedTriggers to handle multiple conditions--> 
      <!--True State--> 
      <ei:PropertyChangedTrigger Binding="{Binding DataContext.IsTrue, 
        RelativeSource={RelativeSource AncestorType={x:Type Window}, Mode=FindAncestor}}" > 
       <i:Interaction.Behaviors> 
        <!--This is just a humble demonstration of Conditional Behavior, it's has so much potential that you can replicate complex if conditions--> 
        <ei:ConditionBehavior> 
         <ei:ConditionalExpression ForwardChaining="And"> 
          <ei:ComparisonCondition Operator="Equal" 
           LeftOperand="{Binding DataContext.IsTrue, RelativeSource={RelativeSource AncestorType={x:Type Window}, Mode=FindAncestor}}" 
           RightOperand="True" 
          /> 
         </ei:ConditionalExpression> 
        </ei:ConditionBehavior> 
       </i:Interaction.Behaviors> 
       <!--I'm not sure why, but I needed to apply the default state first so that the true state plays it's storyboard.--> 
       <!--If you don't do this, this behaves like a data trigger.--> 
       <ei:GoToStateAction StateName="DefaultState"/> 
       <ei:GoToStateAction StateName="TrueState"/> 
      </ei:PropertyChangedTrigger> 

      <!--False state--> 
      <ei:PropertyChangedTrigger Binding="{Binding DataContext.IsTrue, 
        RelativeSource={RelativeSource AncestorType={x:Type Window}, Mode=FindAncestor}}" > 
       <i:Interaction.Behaviors> 
        <ei:ConditionBehavior> 
         <ei:ConditionalExpression ForwardChaining="And"> 
          <ei:ComparisonCondition Operator="Equal" 
           LeftOperand="{Binding DataContext.IsTrue, RelativeSource={RelativeSource AncestorType={x:Type Window}, Mode=FindAncestor}}" 
           RightOperand="False" 
          /> 
         </ei:ConditionalExpression> 
        </ei:ConditionBehavior> 
       </i:Interaction.Behaviors> 
       <ei:GoToStateAction StateName="DefaultState"/> 
      </ei:PropertyChangedTrigger> 
     </i:Interaction.Triggers> 
     <VisualStateManager.VisualStateGroups> 
      <VisualStateGroup x:Name="VisualStateGroup"> 
       <VisualState x:Name="DefaultState"/> 
       <VisualState x:Name="TrueState"> 
        <Storyboard Storyboard.TargetName="txtBox" > 
         <ColorAnimation Storyboard.TargetProperty="Background.Color" From="Transparent" To="Blue" Duration="0:0:0.1" AutoReverse="True" RepeatBehavior="1x" /> 
        </Storyboard> 
       </VisualState> 
      </VisualStateGroup> 
     </VisualStateManager.VisualStateGroups> 
     <TextBox x:Name="txtBox" Text="{Binding DataContext.DisplayText, RelativeSource={RelativeSource AncestorType={x:Type Window}, Mode=FindAncestor}}"/> 
    </Grid> 
</UserControl> 

Bạn có thể sử dụng Nhóm trạng thái trực quan cho việc này. Hơn nữa, tính chất và giá trị hành vi có thể là cả dữ liệu!

Tôi đã thực hiện điều này một cách nhanh chóng trong pha trộn và không kiểm tra. điều này tương tự như giải pháp của tôi.

<UserControl 
      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:i="http://schemas.microsoft.com/expression/2010/interactivity" 
      xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" 
      x:Class="WpfControlLibrary1.UserControl1" 
      mc:Ignorable="d" 
      d:DesignHeight="300" d:DesignWidth="300"> 
    <Grid> 
     <i:Interaction.Behaviors> 
      <ei:DataStateBehavior Binding="{Binding DataContext.IsTrue, 
        RelativeSource={RelativeSource AncestorType={x:Type Window}, Mode=FindAncestor}}" 
       Value="True" 
       TrueState="TrueState"/> 
     </i:Interaction.Behaviors> 
     <VisualStateManager.VisualStateGroups> 
      <VisualStateGroup x:Name="VisualStateGroup"> 
       <VisualState x:Name="DefaultState"/> 
       <VisualState x:Name="TrueState"> 
        <Storyboard Storyboard.TargetName="txtBox" > 
         <ColorAnimation Storyboard.TargetProperty="Background.Color" From="Transparent" To="Blue" Duration="0:0:0.1" AutoReverse="True" RepeatBehavior="1x" /> 
        </Storyboard> 
       </VisualState> 
      </VisualStateGroup> 
     </VisualStateManager.VisualStateGroups> 
     <TextBox x:Name="txtBox" Text="{Binding DataContext.DisplayText, RelativeSource={RelativeSource AncestorType={x:Type Window}, Mode=FindAncestor}}"/> 
    </Grid> 
</UserControl> 
Các vấn đề liên quan