是否有一種在WPF中實現此類控件的最佳方式?在WPF中實現嚮導進度控制
我可以很容易複製的文本標籤和進度條(無每個標籤上面的圓形「顛簸」),但我想知道,如果已經有一個控制在那裏,或最佳實踐,用於在WPF中創建這種控制。
是否有一種在WPF中實現此類控件的最佳方式?在WPF中實現嚮導進度控制
我可以很容易複製的文本標籤和進度條(無每個標籤上面的圓形「顛簸」),但我想知道,如果已經有一個控制在那裏,或最佳實踐,用於在WPF中創建這種控制。
很難說什麼最佳實踐是在這種情況下,但這裏是我如何做到這一點。
在你的屏幕截圖嚮導控制看起來像一個ProgressBar
的組合和ItemsControl
,在這種情況下,它似乎更容易把我從ItemsControl
推導和實施進度功能,那麼周圍的其他方式,但它也取決於你如何希望它的工作(如果你想順利進行或者只是照亮了點一個接一個的例子)。
使用UniformGrid
爲ItemsPanel
及以下ItemTemplate
,我們得到如下的樣子(步驟是一個字符串List
)
<ItemsControl ItemsSource="{Binding Steps}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="1"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Ellipse HorizontalAlignment="Center" Height="20" Width="20" Stroke="Transparent" Fill="Blue"/>
<TextBlock Grid.Row="1" Text="{Binding}" HorizontalAlignment="Center" Margin="0,5,0,0"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
添加DropShadowEffect
到ItemsPanel
,二Path
元素ItemTemplate
和兩個DataTriggers
來確定當前項目是否顯示/隱藏左/右的第一個或最後一個項目,我們可以得到一個非常相似的外觀到您的截圖
ItemsPanel
<UniformGrid Rows="1" SnapsToDevicePixels="True">
<UniformGrid.Effect>
<DropShadowEffect Color="Black"
BlurRadius="5"
Opacity="0.6"
ShadowDepth="0"/>
</UniformGrid.Effect>
</UniformGrid>
的ItemTemplate
<DataTemplate>
<DataTemplate.Resources>
<Style TargetType="Path">
<Setter Property="Data" Value="M0.0,0.0 L0.0,0.33 L1.0,0.33 L1.0,0.66 L0.0,0.66 L0.0,1.0"/>
<Setter Property="StrokeThickness" Value="0"/>
<Setter Property="Height" Value="21"/>
<Setter Property="Stretch" Value="Fill"/>
<Setter Property="Fill" Value="{StaticResource wizardBarBrush}"/>
<Setter Property="StrokeEndLineCap" Value="Square"/>
<Setter Property="StrokeStartLineCap" Value="Square"/>
<Setter Property="Stroke" Value="Transparent"/>
</Style>
</DataTemplate.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Path Name="leftPath"/>
<Path Name="rightPath" Grid.Column="1"/>
<Ellipse Grid.ColumnSpan="2" HorizontalAlignment="Center" Height="20" Width="20" Stroke="Transparent" Fill="{StaticResource wizardBarBrush}"/>
<TextBlock Grid.ColumnSpan="2" Grid.Row="1" Text="{Binding}" HorizontalAlignment="Center" Margin="0,5,0,0"/>
</Grid>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource PreviousData}}"
Value="{x:Null}">
<Setter TargetName="leftPath" Property="Visibility" Value="Collapsed"/>
</DataTrigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Converter={markup:IsLastItemConverter}}"
Value="True">
<Setter TargetName="rightPath" Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
如果你決定使用這種方法,你也許可以鍛鍊如何讓剩下的去,如
DropShadowEffect
),而不是在文本,我上傳了一個名爲WizardProgressBar
的自定義控件示例項目和一個演示項目:https://www.dropbox.com/s/ng9vfi6uwn1peot/WizardProgressBarDemo2.zip?dl=0
看起來像這樣
事情需要注意樣品
DropShadowEffect
和標題或獲得各項目之間的細線(如中所看到的圖片)。我想不出一個簡單的方法來擺脫它,所以也許這畢竟不是最好的辦法:)更新
作出哪裏分裂呈現爲兩個ItemsControls
擺脫各個項目之間的細線的樣本項目中的一些變化。現在看起來像這樣
上傳在這裏:更新
的https://www.dropbox.com/s/ng9vfi6uwn1peot/WizardProgressBarDemo2.zip?dl=0
結束,並在這裏是上述
<LinearGradientBrush x:Key="wizardBarBrush" StartPoint="0.5,0.0" EndPoint="0.5,1.0">
<GradientStop Color="#FFE4E4E4" Offset="0.25"/>
<GradientStop Color="#FFededed" Offset="0.50"/>
<GradientStop Color="#FFFCFCFC" Offset="0.75"/>
</LinearGradientBrush>
IsLastItemConverter
從示例代碼中缺少的部分public class IsLastItemConverter : MarkupExtension, IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
ContentPresenter contentPresenter = value as ContentPresenter;
ItemsControl itemsControl = ItemsControl.ItemsControlFromItemContainer(contentPresenter);
int index = itemsControl.ItemContainerGenerator.IndexFromContainer(contentPresenter);
return (index == (itemsControl.Items.Count - 1));
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotSupportedException();
}
public IsLastItemConverter() { }
public override object ProvideValue(IServiceProvider serviceProvider)
{
return this;
}
}
令人難以置信,完全徹底的答案。你應該得到這個職位的兩倍賞金。謝謝! –
謝謝亞當:)我對示例項目做了一些改變,擺脫了每個項目之間的細線。 –
+1,做得好! –
我也做過類似的事情。在WPF中它實際上相當簡單。基本上我創建了2個矩形並重疊它們。背景中的矩形具有漸變顏色,前景中的矩形是用於遮蓋漸變矩形的灰色區域。
只需調整灰色矩形的寬度即可讓小節向右或向左移動。
下面是我做的,以及XAML的圖像。
<Border BorderThickness="2" BorderBrush="Black" CornerRadius="2">
<Canvas x:Name="canvasMain" Height="80" Width="330" VerticalAlignment="Top" Background="White" SnapsToDevicePixels="True">
<Rectangle x:Name="recMainBar" Height="30" Canvas.Left="0" Canvas.Top="30" Stroke="Black" Width="300">
<Rectangle.Fill>
<LinearGradientBrush EndPoint="1,1" MappingMode="RelativeToBoundingBox" StartPoint="0,0" SpreadMethod="Reflect">
<GradientStop Color="#FFF5400A"/>
<GradientStop Color="#FF54C816" Offset="1"/>
<GradientStop Color="#FF31C614" Offset="0.996"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<!-- Cover of the bar -->
<Rectangle x:Name="recMainBarCover" Height="30" Canvas.Top="30" Canvas.Left="0" Stroke="Black" Width="300" Fill="#FFEBEBEB"/>
<Path Data="M8,34 L24.5,48.95" Fill="Green" Height="6.95" Stretch="Fill" Stroke="Black" Canvas.Top="60" Width="5"/>
<TextBlock FontSize="10" Height="15" Canvas.Left="2.0" TextWrapping="Wrap" Text="0%" Canvas.Top="66.95" Width="16" RenderTransformOrigin="-0.051,-0.9"/>
<Path Data="M8,34 L24.5,48.95" Fill="Green" Height="6.95" Stretch="Fill" Stroke="Black" Canvas.Left="30" Canvas.Top="60" Width="5"/>
<TextBlock FontSize="10" Height="15" Canvas.Left="30" Text="10%" Canvas.Top="66.95" Width="21" RenderTransformOrigin="-0.051,-0.9"/>
<Path Data="M8,34 L24.5,48.95" Fill="Green" Height="6.95" Stretch="Fill" Stroke="Black" Canvas.Left="60" Canvas.Top="60" Width="5"/>
<TextBlock FontSize="10" Height="15" Canvas.Left="60" Text="20%" Canvas.Top="66.95" Width="21" RenderTransformOrigin="-0.051,-0.9"/>
<Path Data="M8,34 L24.5,48.95" Fill="Green" Height="6.95" Stretch="Fill" Stroke="Black" Canvas.Left="90" Canvas.Top="60" Width="5"/>
<TextBlock FontSize="10" Height="15" Canvas.Left="90" Text="30%" Canvas.Top="66.95" Width="21" RenderTransformOrigin="-0.051,-0.9"/>
<Path Data="M8,34 L24.5,48.95" Fill="Green" Height="6.95" Stretch="Fill" Stroke="Black" Canvas.Left="120" Canvas.Top="60" Width="5"/>
<TextBlock FontSize="10" Height="15" Canvas.Left="120" Text="40%" Canvas.Top="66.95" Width="21" RenderTransformOrigin="-0.051,-0.9"/>
<Path Data="M8,34 L24.5,48.95" Fill="Green" Height="6.95" Stretch="Fill" Stroke="Black" Canvas.Left="150" Canvas.Top="60" Width="5"/>
<TextBlock FontSize="10" Height="15" Canvas.Left="145" FontWeight="Bold" Text="50%" Canvas.Top="66.95" Width="31" RenderTransformOrigin="-0.051,-0.9"/>
<Path Data="M8,34 L24.5,48.95" Fill="Green" Height="6.95" Stretch="Fill" Stroke="Black" Canvas.Left="180" Canvas.Top="60" Width="5"/>
<TextBlock FontSize="10" Height="15" Canvas.Left="180" Text="60%" Canvas.Top="66.95" Width="27" RenderTransformOrigin="-0.051,-0.9"/>
<Path Data="M8,34 L24.5,48.95" Fill="Green" Height="6.95" Stretch="Fill" Stroke="Black" Canvas.Left="210" Canvas.Top="60" Width="5"/>
<TextBlock FontSize="10" Height="15" Canvas.Left="210" Text="70%" Canvas.Top="66.95" Width="27" RenderTransformOrigin="-0.051,-0.9"/>
<Path Data="M8,34 L24.5,48.95" Fill="Green" Height="6.95" Stretch="Fill" Stroke="Black" Canvas.Left="240" Canvas.Top="60" Width="5"/>
<TextBlock FontSize="10" Height="15" Canvas.Left="240" Text="80%" Canvas.Top="66.95" Width="27" RenderTransformOrigin="-0.051,-0.9"/>
<Path Data="M8,34 L24.5,48.95" Fill="Green" Height="6.95" Stretch="Fill" Stroke="Black" Canvas.Left="270" Canvas.Top="60" Width="5"/>
<TextBlock FontSize="10" Height="15" Canvas.Left="270" Text="90%" Canvas.Top="66.95" Width="27" RenderTransformOrigin="-0.051,-0.9"/>
<Path Data="M8,34 L24.5,48.95" Fill="Green" Height="6.95" Stretch="Fill" Stroke="Black" Canvas.Left="300" Canvas.Top="60" Width="5"/>
<TextBlock FontSize="10" Height="15" Canvas.Left="300" Text="100%" Canvas.Top="66.95" Width="27" RenderTransformOrigin="-0.051,-0.9"/>
<TextBlock Name="txtTitle" FontSize="16" FontWeight="Bold" Background="Black" Foreground="White" Height="30" Canvas.Left="0" Text="Confidence Factor" Canvas.Top="0" Width="330" HorizontalAlignment="Center" TextAlignment="Center"/>
</Canvas>
</Border>
正如我所說的,重新創建文本標籤和進度(沒有在每個標籤上碰撞)很容易。我期待完全複製我發佈爲可重用控件的設計。 –
你可以繪製完整的進度指示器,建立進度指示器剪貼蒙版,並且無論是改變或與程序的執行過程中,在適當的點的另一個面具掩蓋掉。如果你想得到真正的創意,你可以制定一個控制,可以定義任意數量的點。
本文告訴您有關通用剪貼蒙版中表達:http://expression.microsoft.com/en-us/cc197119
本文將向您展示一些代碼,可能會多一點有關: http://blog.pixelingene.com/2009/02/animating-graphs-in-wpf-using-clipping-masks/ 並在此代碼,你可以輕鬆地調整運行時的RectangleGeometry 。
所以我從所有這些閱讀和琢磨明白的是,你可能嘗試在你的藍色進度指示器剪輯屬性,並保留背景原樣。
這是我可能採取的路線。希望這可以幫助!
我不認爲現在有什麼特別的東西。我猜你想要標籤和百分比是動態的嗎? – Stimul8d
優選地。我想能夠放入一個'ItemsControl'(或其他列表)的標籤,並選擇一個當前的步驟或索引,但我打開其他選項。 –