1

在WPF中,我有一個ListBox,其中的列表由UserControls組成。這些控件旨在導航到應用程序中的不同屏幕。每個UserControl(稱爲NavigationButton)都有一個圖標和文本。這些圖標大多是多個Path對象的組合,因此每個圖標都是它自己的UserControl,並使用ContentPresenter顯示它們。我希望能夠根據屏幕的不同狀態爲圖標的顏色設置動畫,但嘗試了很多選項並且無法做到這一點。通過ContentPresenter顯示的UserControl上的Animate DependencyProperty

這裏是NavigationButton的一個精簡版:

<DockPanel Margin="12,0,12,0"> 

     <!-- Icon --> 
     <ContentPresenter x:Name="Content_Icon" Content="{Binding}" Width="20"/> 

     <!-- Text --> 
     <Grid Margin="9,0,0,0"> 
      <TextBlock x:Name="TextBlock_Text" Text="{Binding ScreenName, Converter={StaticResource StringToStringUpperConverter}}" VerticalAlignment="Center" 
         FontSize="15" Foreground="#FFF2F2F2" /> 
     </Grid> 

基本上,我需要動畫在ContentPresenter的屬性,但不知道如何訪問它。

這裏是列表框託管NavigationButtons:

 <ListBox DockPanel.Dock="Top" ItemsSource="{Binding ScreenViewModels}" 
      SelectedItem="{Binding SelectedScreenViewModel}"> 

     <ListBox.ItemTemplate> 
      <DataTemplate> 
       <my:NavigationButton/> 
      </DataTemplate> 
     </ListBox.ItemTemplate> 

我創建了一個基礎用戶控件(稱爲IconBaseControl),所有這些圖標UserConrols的可以繼承。基本控件具有Brush DependencyProperty,稱爲IconFill。在可以改變圖標的​​路徑的部分被綁定到這個屬性:

<Path Data="<data>" Fill="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type my:IconBaseControl}}, Path=IconFill}" 

我知道綁定工作正常,因爲顏色時,我改變對用戶控件默認的顏色變化。理想情況下,我想使用VisualStateManager,因爲會有很多不同的狀態。所以,我在NavigationButton上有一個VisualStateManager,UserControl包含承載圖標的ContentPresenter(繼承IconBaseControl的所有UserControls),名爲Content_Icon。我試圖在狀態之一是這樣的:

<VisualState x:Name="Deselected"> 
      <Storyboard> 

       <ColorAnimation Storyboard.TargetName="TextBlock_Text" Storyboard.TargetProperty="Foreground.Color" 
         To="#FF5e5e5e" Duration="0"/> 

       <ColorAnimation Storyboard.TargetName="Content_Icon" Storyboard.TargetProperty="IconFill" 
         To="#FF5e5e5e" Duration="0"/> 

      </Storyboard> 
</VisualState> 

,但我得到了以下錯誤:

出現InvalidOperationException:無法解析的屬性路徑的所有屬性引用「IconFill」。驗證適用的對象是否支持這些屬性。

我也試過像這樣的東西結合故事板的屬性:

Storyboard.TargetProperty="(IconBaseControl.IconFill) 

但得到這個錯誤:

IconBaseControl不是在的Windows Presentation Foundation(WPF)項目的支持。

我也試過在代碼背後搞亂,但無法弄清楚如何將ContentPresenter轉換爲IconBaseControl。我覺得ContentTemplate屬性是一條路,但它沒有。

關於如何動畫這個屬性的任何建議?打開幾乎任何東西:)我在VB.Net編碼,但任何C#建議也很好。

在此先感謝。

編輯:爲NavigationButton

回答

1

包含的代碼我發現WPF控件創建子類會導致混亂,是沒有必要的,除非它是一個非常先進的問題。在我看來,將IconBaseControl創建爲UserControl的子項在你的場景中是過分的。

這是我的建議,假設您使用的是MVVM:將IconBaseControl創建爲普通的UserControl。只需使用IconControl.xaml.cs代碼創建一個IconControl.xaml,就像其他任何視圖一樣。

這裏是你會內部IconControl什麼一個例子:

<UserControl> 
    <Grid> 
    <Grid.ColumnDefinitions> 
     <ColumnDefinition /> 
     <ColumnDefinition /> 
    </Grid.ColumnDefinitions> 
    <Grid.Style> 
     <Style> 
      <Style.Triggers> 
       <DataTrigger Binding="{Binding IsSelected}" Value="True"> 
        <DataTrigger.EnterActions> 
         <BeginStoryboard> 
          <Storyboard> 
           <ColorAnimation Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)" To="#FF5e5e5e" Duration="0:0:0" /> 
          </Storyboard> 
         </BeginStoryboard> 
        </DataTrigger.EnterActions> 
        <DataTrigger.ExitActions> 
         <BeginStoryboard> 
          <Storyboard> 
           <ColorAnimation Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)" To="White" Duration="0:0:0" /> 
          </Storyboard> 
         </BeginStoryboard> 
        </DataTrigger.ExitActions> 
       </DataTrigger> 
      </Style.Triggers> 
     </Style> 
    </Grid.Style> 

    <Image Source="Icon.jpeg" /> 

    <TextBlock Text="{Binding PageName}" Grid.Column="1" /> 

</Grid> 
</UserControl>` 

注意周邊電網的背景將改變基於綁定到一個名爲IsSelected在DataContext的價值。因此,此時您需要創建一個名爲IconControlViewModel.cs的ViewModel,並將IsSelected布爾值暴露爲依賴項屬性。

最後包含這些導航按鈕的觀點:

<UserControl> 

    <ItemsControl ItemsSource="{Binding ListOf_IconControlViewModels}"> 
     <ItemsControl.ItemTemplate> 
      <DataTemplate DataType="{x:Type IconControlViewModel}"> 
       <local:IconView /> 
      </DataTemplate> 
     </ItemsControl.ItemTemplate> 
    </ItemsControl> 

</UserControl> 

通知,告訴ItemsControl的,當它看到一個IconControlViewModel中的ItemsSource列表呈現什麼DataTemplate中。這就是我將如何使用MVVM模式進行設計的。我希望這可以幫助,並讓我知道,如果你需要澄清我的答案,或者它的方式。

乾杯, 埃裏克

+0

感謝您的答覆!唯一的問題是我在控件中使用ContentPresenter根據控件的DataContext顯示不同的圖標。列表框綁定到視圖模型列表,每個代表不同的屏幕。所以每個屏幕都需要有自己的圖標。這就是問題出現的地方,我無法訪問ContentPresenter上的任何屬性。這就是爲什麼我試圖使用繼承來使它們都是相同類型的原因,但這並沒有真正讓我獲得任何地方。 – Riggs

+0

我很難想象您的設計,但有時使用轉換器在需要對UI進行復雜更改時很有用,例如圖標。所以你可以做的是將圖像的源代碼綁定到ViewModel上的一個值(枚舉可以工作)。然後在該綁定上使用轉換器,該轉換使用該枚舉值並返回正確的圖標。如果你想包括更多的代碼,我可能會幫助更多。 – baueric

+0

或者你可以像這樣綁定Image源代碼:Source =「{Binding Converter = {StaticResource MyIconConverter}}」。這將做的是將整個DataContext傳遞給轉換器。然後,您可以根據DataContext的類類型返回正確的圖標。 – baueric

相關問題