2013-07-01 62 views
0

所以,我爲每個控件和ValidationErrorTemplate獲得了一個巨大的樣式模板字典。問題是,當控制器上方沒有位置時,我們應該在控制下顯示驗證錯誤。基本上用於窗口頂部的控件。對於窗口底部的控件,驗證應顯示在控件的上方。WPF ValidationErrorTemplate風格動態位置

既然,每一個樣式定義存在沒有代碼隱藏資源字典,也沒有數據綁定是可能的。

一個想法是確定AdornedElementPlaceholder的位置並分別隱藏/顯示模板。但是我沒有找到任何解決方案來做到這一點在XAML。

<ControlTemplate x:Key="ValidationErrorTemplate"> 
     <Grid> 
      <Grid.RowDefinitions> 
       <RowDefinition Height="Auto"/> 
       <RowDefinition Height="Auto"/> 
       <RowDefinition Height="Auto"/> 
      </Grid.RowDefinitions> 
      <Grid Grid.Row="1"> 
       <Border> 
        <AdornedElementPlaceholder /> 
       </Border>     
      </Grid> 
      <AdornerDecorator Grid.Row="????"> 
       <Border > 
        <!-- some style comes here ... --> 
       </Border> 
      </AdornerDecorator> 
     </Grid> 
    </ControlTemplate> 

Grid.Row = 「????」應該爲0或1,具體取決於控件的頂部。

回答

0

所以我終於找到了解決方案:附屬性。我創建了一個attach屬性,並在AdornerDecorator.Loaded事件上訂閱了屬性更改回調方法。在該方法中,您可以檢查實際位置並根據需要更改屬性。

[示例代碼片段,在真正的源頭更外包和複查,由於特定的代碼問題]

private static void DecoratorLoaded(object obj, RoutedEventArgs e) 
{ 
    var decorator = obj as Decorator; 
    if (decorator != null && decorator.IsVisible) 
    { 
     // get the position 
     Point renderedLocation = decorator.TranslatePoint(new Point(0, 0), Application.Current.MainWindow); 
     if (renderedLocation != new Point(0, 0)) 
     { 
      // check width 
      var maxAllowedWidth = Application.Current.MainWindow.ActualWidth - renderedLocation.X - 40;    
      decorator.SetValue(FrameworkElement.MaxWidthProperty, maxAllowedWidth); 

      // check place above the control 
      var isEnoughPlaceAbove = renderedLocation.Y > decorator.ActualHeight + 10; 
      decorator.SetValue(Grid.RowProperty, isEnoughPlaceAbove ? 0 : 2); 

      // invalidate to re-render 
      decorator.InvalidateVisual();    
     } 
    } 
} 

您需要使用Loaded事件,以確保renderLocation將提供您的實際位置而不是別的(例如零或一些相對位置)。

最後,您需要附加屬性附加到裝飾在XAML:

<AdornerDecorator Behaviors:AdornerPositionCalculator.AllowDynamicPosition="True"> 
    <!-- custom style here --> 
</AdornerDecorator> 
0

有兩個單獨的模板(一個是另一個的對面),並且使用一個用於頂部的項目,一個用於底部的項目,只要任何對象包含您正在說的控件的任何對象。

+0

聽起來不錯,但我們不希望定義明確的風格與一鍵每一個控制。 Specialy不是,因爲我們開發了一個框架,所以不能保證他們不會忘記添加正確的樣式鍵。 –

+0

您是否想過使用DataTrigger來設置Grid.Row,取決於AdornedElementPlaceholder的值?我從來沒有嘗試過這個,但我認爲它會按照你描述的方式工作。 – Killingsworth