WPF

2011-10-07 5 views
24

में एक विज़ार्ड प्रगति नियंत्रण लागू करना क्या WPF में इस तरह के नियंत्रण को लागू करने का सबसे अच्छा तरीका है?WPF

Wizard Progress Control

मैं आसानी से पाठ लेबल और प्रगति बार (प्रत्येक लेबल ऊपर परिपत्र "बम्प्स" के बिना) को दोहराने कर सकते हैं, लेकिन मैं वहाँ एक नियंत्रण पहले से ही वहाँ बाहर है अगर जानना चाहते हैं, या एक सबसे अच्छा अभ्यास , WPF में इस तरह के नियंत्रण बनाने के लिए।

+0

मुझे नहीं लगता कि अभी इस तरह कुछ भी है। मुझे लगता है कि आप लेबल्स और प्रतिशत के गतिशील गति के लिए चाहते हैं? – Stimul8d

+0

पसंदीदा रूप से। मैं लेबल की 'आइटम नियंत्रण' (या अन्य सूची) में ड्रॉप करने में सक्षम होना चाहता हूं और वर्तमान चरण या अनुक्रमणिका का चयन करना चाहता हूं, लेकिन मैं अन्य विकल्पों के लिए खुला हूं। –

उत्तर

63

यह कहना मुश्किल है कि सर्वोत्तम अभ्यास इस मामले में है, लेकिन यहां यह है कि मैं इसे कैसे करूँगा।

अपने स्क्रीनशॉट में जादूगर नियंत्रण एक ItemsControl और इस मामले में यह मेरे लिए आसान लगता है ItemsControl से निकाले जाते हैं और प्रगति कार्यक्षमता तो दूसरी तरह के आसपास लागू करने के लिए लेकिन यह भी आप कैसे पर निर्भर करता है एक ProgressBar का एक संयोजन और की तरह दिखता है इसे पर काम करना चाहते हैं (यदि आप एक चिकनी प्रगति चाहते हैं या उदाहरण के लिए डॉट्स को एक-एक करके जलाएं)

का उपयोग कर एक UniformGridItemsPanel के रूप में और नीचे ItemTemplate, हम निम्नलिखित नज़र प्राप्त एक DropShadowEffect को ItemsPanel, दो Path के तत्वों को जोड़ने
enter image description here

<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> 

(कदम तार का एक List है) ItemTemplate और दो DataTriggers यह निर्धारित करने के लिए कि वर्तमान आइटम बाएं/दाएंको दिखाने/छिपाने के लिए पहली या आखिरी वस्तु है या नहींऔर हम अपने स्क्रीनशॉट के लिए एक बहुत समान दृष्टिकोण प्राप्त कर सकते
enter image description here

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> 

आप इस दृष्टिकोण आप शायद कसरत कर सकते हैं उपयोग करना चाहते हैं इसे बाकी कैसे प्राप्त करें, जैसे

  • एक Resuable कस्टम नियंत्रण में इस लागू
  • केवल प्रगति-भाग पर स्ट्रोक (DropShadowEffect) और नहीं पाठ में
  • वैसे भी प्रगति कार्यक्षमता आदि

लागू मिलता है, मैं एक कस्टम नियंत्रण के साथ एक नमूना परियोजना WizardProgressBar बुलाया अपलोड की गई और एक डेमो परियोजना यहां उसका उपयोग करना: https://www.dropbox.com/s/ng9vfi6uwn1peot/WizardProgressBarDemo2.zip?dl=0

यह इस
तरह लग रहा हैenter image description here

हालात नमूना

  • मैं एक स्थिति में समाप्त हो गया है, जहां मैं प्रगति-भाग पर DropShadowEffect और हेडर मिलता है या (के रूप में के रूप में देखा प्रत्येक आइटम के बीच एक पतली रेखा मिलेगा के बारे में नोट करने के लिए चित्र)। मैं इससे छुटकारा पाने का एक आसान तरीका नहीं सोच सकता, इसलिए शायद यह सब के बाद सबसे अच्छा तरीका नहीं है :)
  • प्रगति-भाग सरल है। यह सिर्फ 0-100 के बीच एक मान है और फिर एक कनवर्टर तय करता है कि आइटम को जलाया जाना चाहिए या नहीं
  • इस नियंत्रण का एक छोटा प्रदर्शन प्रभाव हो सकता है लेकिन मुझे यकीन नहीं है क्योंकि मेरा कंप्यूटर आज सब कुछ धीमा चल रहा है ..

अद्यतन

नमूना परियोजना जहाँ मैं दो ItemsControls में प्रस्तुति splitted प्रत्येक आइटम के बीच पतली लाइनों से छुटकारा पाने के लिए कुछ बदलाव किए हैं।अब ऐसा लगता है कि इस
enter image description here
इसे यहाँ अपलोड किया गया: अद्यतन

की 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; 
    } 
} 
+5

अविश्वसनीय, पूरी तरह से पूर्ण जवाब। आप इस पोस्ट के लिए प्राप्त दो बार बकाया के लायक हैं। धन्यवाद! –

+0

धन्यवाद एडम :) मैंने नमूना प्रोजेक्ट में कुछ बदलाव किए हैं जो प्रत्येक आइटम के बीच पतली रेखा से छुटकारा पाता है। –

+1

+1, अच्छी तरह से किया !! –

2

मैंने कुछ भी ऐसा ही किया। यह वास्तव में डब्ल्यूपीएफ में काफी आसान है। असल में मैंने 2 आयताकार बनाए और उन्हें ओवरलैप किया। पृष्ठभूमि में आयताकार में ढाल रंग होते हैं और अग्रभूमि में आयत ग्रेडिएंट आयत को ढंकने के लिए उपयोग किया जाता है।

दाएं या बाएं चलने वाले बार के भ्रम को देने के लिए बस ग्रे आयताकार की चौड़ाई समायोजित करें।

नीचे एक्सएएमएल के साथ मैंने जो किया, उसकी एक छवि है।

enter image description here

<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> 
+1

जैसा कि मैंने कहा, पाठ लेबल और प्रगति को पुनर्जीवित करना (प्रत्येक लेबल पर टक्कर के बिना) आसान है। मैं एक पुन: प्रयोज्य नियंत्रण के रूप में पोस्ट किए गए डिज़ाइन को बिल्कुल दोहराना चाहता हूं। –

0

पूर्ण प्रगति संकेतक आकर्षित कर सकता है, प्रगति संकेतक के लिए एक कतरन मुखौटा की स्थापना की, और या तो बदल या स्वैप कि अपने कार्यक्रम के निष्पादन के दौरान उचित बिंदुओं पर एक और मुखौटा के साथ मुखौटा। यदि आप वास्तव में रचनात्मक होना चाहते हैं, तो आप एक नियंत्रण कर सकते हैं जो अंक की किसी भी मनमानी संख्या को परिभाषित कर सकता है।

यह लेख अभिव्यक्ति में जेनेरिक कतरन मास्क के बारे में बताता: http://expression.microsoft.com/en-us/cc197119

यह लेख आपको कुछ कोड है कि एक छोटे से अधिक प्रासंगिक हो सकता है पता चलता है: http://blog.pixelingene.com/2009/02/animating-graphs-in-wpf-using-clipping-masks/ और इस कोड में, आप आसानी से कार्यावधि में RectangleGeometry समायोजित कर सकते हैं ।

तो मुझे यह सब पढ़ने और सोचने से क्या मिलता है कि आप संभवतः क्लिप नीली प्रगति संकेतक पर क्लिप प्रॉपर्टी का प्रयास करेंगे, और पृष्ठभूमि को छोड़ दें।

यही वह मार्ग है जो मैं शायद लेता हूं। उम्मीद है की यह मदद करेगा!

संबंधित मुद्दे