2011-02-09 14 views
5

Tôi có một wpftoolkit khá đơn giản: datagrid để hiển thị giá thầu thị trường chứng khoán và yêu cầu.Làm thế nào để tạo hiệu ứng nền của một khối văn bản khi thay đổi giá trị của thuộc tính bị ràng buộc?

Lưới của tôi bị ràng buộc vào ObservableCollection<PriceViewModel>. My PriceViewModel thực hiện INotifyPropertyChanged.

Lưới được cập nhật chính xác và tôi đã quản lý để làm cho màu nền hoạt ảnh nhưng không liên tục áp dụng hoạt ảnh.

Dưới đây là XAML và đoạn trích của lớp mô hình chế độ xem.

Ý tưởng chỉ để tô màu đỏ khi bản cập nhật giá thấp hơn màu trước đó và màu xanh lá cây khi nó cao hơn ... không có gì quá lạ mắt.

 <WpfToolkit:DataGrid Name="PriceDataGrid" RowHeaderWidth="5" 
AutoGenerateColumns="False" VerticalContentAlignment="Center" Margin="0,33,0,0" HorizontalAlignment="Left" Width="868"> 
     <WpfToolkit:DataGrid.Columns> 
      <WpfToolkit:DataGridTemplateColumn Header="Bid" MinWidth="40"> 
       <WpfToolkit:DataGridTemplateColumn.CellTemplate> 
        <DataTemplate> 
         <TextBlock Text="{Binding Bid}" Margin="3,1" x:Name="txtTextBlock"> 
          <TextBlock.Background> 
           <SolidColorBrush Color="Transparent"></SolidColorBrush> 
          </TextBlock.Background> 
         </TextBlock> 
         <DataTemplate.Triggers> 
          <DataTrigger Binding="{Binding BidUp}" Value="True"> 
           <DataTrigger.EnterActions> 
            <BeginStoryboard> 
             <Storyboard> 
              <ColorAnimation 
               BeginTime="00:00:00" 
               Duration="0:0:0.1" 
               To="Green" 
               AutoReverse="True" 
               Storyboard.TargetName="txtTextBlock" 
               Storyboard.TargetProperty="(TextBlock.Background).(SolidColorBrush.Color)"> 
              </ColorAnimation> 
             </Storyboard> 
            </BeginStoryboard> 
           </DataTrigger.EnterActions> 
          </DataTrigger> 
          <DataTrigger Binding="{Binding BidDown}" Value="True"> 
           <DataTrigger.EnterActions> 
            <BeginStoryboard> 
             <Storyboard> 
              <ColorAnimation 
               BeginTime="00:00:00" 
               Duration="0:0:0.1" 
               To="Red" 
               AutoReverse="True" 
               Storyboard.TargetName="txtTextBlock" 
               Storyboard.TargetProperty="(TextBlock.Background).(SolidColorBrush.Color)"> 
              </ColorAnimation> 
             </Storyboard> 
            </BeginStoryboard> 
           </DataTrigger.EnterActions> 
          </DataTrigger> 
         </DataTemplate.Triggers> 
        </DataTemplate> 
       </WpfToolkit:DataGridTemplateColumn.CellTemplate> 
      </WpfToolkit:DataGridTemplateColumn> 
      <WpfToolkit:DataGridTextColumn Header="Ask" Binding="{Binding Path=Ask}" MinWidth="40" /> 
     </WpfToolkit:DataGrid.Columns> 
    </WpfToolkit:DataGrid> 

Và mô hình điểm:

public class PriceViewModel : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    Price _price; 

    private bool _bidUp = false; 
    private bool _bidDown = false; 


    public bool BidUp 
    { 
     get 
     { 
      return _bidUp; 
     } 

     set 
     { 
      _bidUp = value; 
      OnPropertyChanged("BidUp"); 
     } 
    } 
    public bool BidDown 
    { 
     get 
     { 
      return _bidDown; 
     } 

     set 
     { 
      _bidDown = value; 
      OnPropertyChanged("BidDown"); 
     } 
    } 

    public double Bid 
    { 
     get { return _price.Bid; } 
     set 
     { 
      BidUp = (value > _price.Bid); 
      BidDown = (value < _price.Bid); 

      _price.Bid = value; 
      OnPropertyChanged("Bid"); 
     } 
    } 

    public double Ask 
    { 
     get { return _price.Ask; } 
     set 
     { 
      AskUp = (value > _price.Ask); 
      _price.Ask = value; 
      OnPropertyChanged("Ask"); 
     } 
    } 


    public PriceViewModel(Price price) 
    { 
     _price = price; 
    } 

    private void OnPropertyChanged(string propertyName) 
    { 
     if(PropertyChanged != null) 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
    } 

} 

Trả lời

9

tôi đã cố gắng này và nó dường như làm việc tốt hơn nếu bạn ngừng các Storyboard s trước khi bắt đầu cái mới. Để ngăn chặn một Storyboard, đặt tên cho nó và gọi

<StopStoryboard BeginStoryboardName="bidUpStoryboard"/> 

Hãy thử nó như thế này

<DataTemplate.Triggers> 
    <DataTrigger Binding="{Binding BidUp}" Value="True"> 
     <DataTrigger.EnterActions> 
      <StopStoryboard BeginStoryboardName="bidUpStoryboard"/> 
      <StopStoryboard BeginStoryboardName="bidDownStoryboard"/> 
      <BeginStoryboard Name="bidUpStoryboard"> 
       <Storyboard BeginTime="00:00:00"> 
        <ColorAnimation 
         BeginTime="00:00:00" 
         Duration="0:0:0.1" 
         To="Green" 
         AutoReverse="True" 
         Storyboard.TargetName="txtTextBlock" 
         Storyboard.TargetProperty="(TextBlock.Background).(SolidColorBrush.Color)"> 
        </ColorAnimation> 
       </Storyboard> 
      </BeginStoryboard> 
     </DataTrigger.EnterActions> 
    </DataTrigger> 
    <DataTrigger Binding="{Binding BidDown}" Value="True"> 
     <DataTrigger.EnterActions> 
      <StopStoryboard BeginStoryboardName="bidUpStoryboard"/> 
      <StopStoryboard BeginStoryboardName="bidDownStoryboard"/> 
      <BeginStoryboard Name="bidDownStoryboard"> 
       <Storyboard BeginTime="00:00:00"> 
        <ColorAnimation 
         BeginTime="00:00:00" 
         Duration="0:0:0.1" 
         To="Red" 
         AutoReverse="True" 
         Storyboard.TargetName="txtTextBlock" 
         Storyboard.TargetProperty="(TextBlock.Background).(SolidColorBrush.Color)"> 
        </ColorAnimation> 
       </Storyboard> 
      </BeginStoryboard> 
     </DataTrigger.EnterActions> 
    </DataTrigger> 
</DataTemplate.Triggers> 

Ngoài ra, nếu BidUp được thiết lập là true hai lần liên tiếp, nó sẽ không kích hoạt lần thứ hai kể từ khi nó sẽ chuyển từ true thành true, vì vậy nếu bạn muốn hiệu ứng nhấp nháy xuất hiện mỗi khi một giá trị thay đổi, bạn sẽ phải đặt nó thành false tại một số điểm. ví dụ.

public double Bid 
{ 
    get { return _price.Bid; } 
    set 
    { 
     BidUp = false; 
     BidDown = false; 
     BidUp = (value > _price.Bid); 
     BidDown = (value < _price.Bid); 
     _price.Bid = value; 
     OnPropertyChanged("Bid"); } 
} 
+0

Làm việc tuyệt vời. Nói chung cách tiếp cận của tôi cảm thấy một chút phức tạp, là có một mô hình tốt hơn cho loại hành vi này hoặc một cách tôi có thể genericize kích hoạt của tôi? – MattC

+0

Chúng ta có thể thực hiện phương pháp này mà không cần sử dụng DataGrid không? – Alkimake

0

Một giải pháp thay thế có thể có một số thuộc tính trên PriceViewModel - một cho mỗi giá thầu và vùng hỏi lại. Sau đó, bạn có thể có một bộ sưu tập theo dõi các mục trong số ObserveableCollection đã được cập nhật. Bộ định thời sẽ định kỳ kiểm tra bộ sưu tập này và đặt lại ô trở lại màu đã được đặt lại.

Một ví dụ ở đây:

http://noelwatson.com/blog/2012/05/01/WPFBlotterflashingCellsWhenUpdated.aspx

Các vấn đề liên quan