2008-09-23 13 views
90

हम एक एक्सबीएपी आवेदन बना रहे हैं कि हमें एक ही पृष्ठ में विभिन्न स्थानों में गोलाकार कोनों की आवश्यकता है और हम एक WPF गोलाकार कॉर्नर कंटेनर चाहते हैं ताकि अन्य तत्वों का एक समूह हो सके। क्या किसी के पास कुछ सुझाव या नमूना कोड है कि हम इसे कैसे पूरा कर सकते हैं? या तो कस्टम नियंत्रण बनाने के साथ या शैलियों के साथ?मैं एक डब्ल्यूपीएफ गोलाकार कॉर्नर कंटेनर कैसे बना सकता हूं?

+1

चेतावनी: यदि आप एक गोल आयत सीमा के अंदर का पाठ की एक पंक्ति में कहें, मेरे जैसे पुराने लोगों को यह देखने के लिए और सोचेंगे, "Macintosh 80 के दशक बटन पुश!" – mjfgates

+0

आपको पता नहीं है कि मैं 80 के मैकिंटोश को कितनी बुरी तरह याद करता हूं! मुझे लगता है कि इस सवाल को स्पष्ट रूप से यह बताना चाहिए कि कोनों को क्लिप करना चाहते हैं या नहीं, क्योंकि चयनित उत्तर सीमा को क्लिप नहीं करता है। –

उत्तर

223

आप एक कस्टम नियंत्रण की आवश्यकता नहीं है, बस एक सीमा तत्व में अपने कंटेनर को:

<Border BorderBrush="#FF000000" BorderThickness="1,1,1,1" CornerRadius="8,8,8,8"> 
    <Grid/> 
</Border> 

आप लेआउट कंटेनर से किसी के साथ <Grid/> जगह ले सकता है ...

+27

किसी भी मोटाई ऑब्जेक्ट (सीमाबद्धता या कॉर्नर रेडियस) के लिए आप एक ही संख्या निर्दिष्ट कर सकते हैं यदि सभी 4 समान हैं, जैसे CornerRadius = "8"। –

+0

क्या आप जानते थे? आप कमाल कर रहे हैं! Fyi आप कमाल कर रहे हैं! –

+2

'<सीमा सीमावर्ती ब्रश =" काला "सीमाचित्रता =" 1 "कॉर्नर रेडियस =" 8 ">' इसके लिए एक उपयुक्त प्रतिस्थापन है, थोड़ा और अधिक अंक –

49

मैं जानता हूँ कि यह प्रारंभिक प्रश्न का उत्तर नहीं है ... लेकिन आप अक्सर उस गोलाकार कोने सीमा की आंतरिक सामग्री को क्लिप करना चाहते हैं जिसे आपने अभी बनाया है।

क्रिस कैवानाघ ने ऐसा करने के लिए excellent way के साथ आ गया है।

मैंने इस पर दो अलग-अलग दृष्टिकोणों की कोशिश की है ... और मुझे लगता है कि यह एक चट्टान है।

<Page 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Background="Black" 
> 
    <!-- Rounded yellow border --> 
    <Border 
     HorizontalAlignment="Center" 
     VerticalAlignment="Center" 
     BorderBrush="Yellow" 
     BorderThickness="3" 
     CornerRadius="10" 
     Padding="2" 
    > 
     <Grid> 
      <!-- Rounded mask (stretches to fill Grid) --> 
      <Border 
       Name="mask" 
       Background="White" 
       CornerRadius="7" 
      /> 

      <!-- Main content container --> 
      <StackPanel> 
       <!-- Use a VisualBrush of 'mask' as the opacity mask --> 
       <StackPanel.OpacityMask> 
        <VisualBrush Visual="{Binding ElementName=mask}"/> 
       </StackPanel.OpacityMask> 

       <!-- Any content --> 
       <Image Source="http://chriscavanagh.files.wordpress.com/2006/12/chriss-blog-banner.jpg"/> 
       <Rectangle 
        Height="50" 
        Fill="Red"/> 
       <Rectangle 
        Height="50" 
        Fill="White"/> 
       <Rectangle 
        Height="50" 
        Fill="Blue"/> 
      </StackPanel> 
     </Grid> 
    </Border> 
</Page> 
+1

ब्लैकलाइट कंट्रोल (http://blacklight.codeplex.com/) में निफ्टी छोटे नियंत्रण भी हैं जिन्हें क्लिपिंगबॉर्डर कहा जाता है जो आपको सामग्री को अपने गोलाकार कोनों पर क्लिप करने की अनुमति देता है। ClippingBorder के बारे में एक अच्छी बात यह है कि यह विजुअलब्रश का उपयोग नहीं करता है (जो उच्चतम लागत (प्रदर्शन के संदर्भ में) ब्रश में से एक है)। – cplotts

+1

हालांकि, मैंने अभी क्लिपिंगबॉर्डर के कार्यान्वयन के अंदर एक नज़र डाली है ... और यह 4 कंटेंट कंट्रोल (ओं) का उपयोग अपने डिफ़ॉल्ट कंट्रोल टेम्पलेट (प्रत्येक कोने के लिए एक) में करता है ... इसलिए मुझे यकीन नहीं है कि यह अधिक है या नहीं उपरोक्त VisualBrush दृष्टिकोण से कम प्रदर्शन करने वाला। मैं शायद कम प्रदर्शन करने वाला अनुमान लगाऊंगा। – cplotts

+0

क्लिपिंग की आवश्यकता होने पर यह उत्तर चुना जाना चाहिए। –

1

आप एक गोल आयत सीमा में एक बटन रखने की कोशिश कर रहे हैं, तो आप msdn's example की जांच करनी चाहिए:

यहाँ नीचे XAML है। मैंने इसे समस्या की छवियों (पाठ के बजाय) के लिए googling द्वारा पाया। उनका भारी बाहरी आयताकार (धन्यवाद) को हटाने में आसान है।

ध्यान दें कि आपको बटन के व्यवहार को फिर से परिभाषित करना होगा (क्योंकि आपने ControlTemplate को बदल दिया है)। यही है, आपको ControlTemplate.Triggers टैग में एक ट्रिगर टैग (प्रॉपर्टी = "IsPressed" Value = "true") का उपयोग करके क्लिक किए जाने पर बटन के व्यवहार को परिभाषित करने की आवश्यकता होगी। उम्मीद है कि यह किसी और को खोने का समय बचाता है :)

12

मुझे बस इसे खुद करना पड़ा, इसलिए मैंने सोचा कि मैं यहां एक और जवाब पोस्ट करूंगा।

गोलाकार कोने सीमा बनाने और इसकी आंतरिक सामग्री क्लिप करने का एक और तरीका है। क्लिप संपत्ति का उपयोग करके यह सीधा तरीका है। यदि आप VisualBrush से बचना चाहते हैं तो यह अच्छा है।

XAML:

<Border 
    Width="200" 
    Height="25" 
    CornerRadius="11" 
    Background="#FF919194" 
> 
    <Border.Clip> 
     <RectangleGeometry 
      RadiusX="{Binding CornerRadius.TopLeft, RelativeSource={RelativeSource AncestorType={x:Type Border}}}" 
      RadiusY="{Binding RadiusX, RelativeSource={RelativeSource Self}}" 
     > 
      <RectangleGeometry.Rect> 
       <MultiBinding 
        Converter="{StaticResource widthAndHeightToRectConverter}" 
       > 
        <Binding 
         Path="ActualWidth" 
         RelativeSource="{RelativeSource AncestorType={x:Type Border}}" 
        /> 
        <Binding 
         Path="ActualHeight" 
         RelativeSource="{RelativeSource AncestorType={x:Type Border}}" 
        /> 
       </MultiBinding> 
      </RectangleGeometry.Rect> 
     </RectangleGeometry> 
    </Border.Clip> 

    <Rectangle 
     Width="100" 
     Height="100" 
     Fill="Blue" 
     HorizontalAlignment="Left" 
     VerticalAlignment="Center" 
    /> 
</Border> 

कनवर्टर के लिए कोड: kobusb की सीमा नियंत्रण समाधान के

public class WidthAndHeightToRectConverter : IMultiValueConverter 
{ 
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) 
    { 
     double width = (double)values[0]; 
     double height = (double)values[1]; 
     return new Rect(0, 0, width, height); 
    } 
    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 
+0

बहुत अच्छा समाधान। मैं एक बटन के लिए एक नियंत्रण टेम्पलेट बना रहा हूं जिसके लिए अलग-अलग राज्यों में बाहरी चमक और आंतरिक चमक दोनों की आवश्यकता है, और इससे समस्या को हल करने में मदद मिली। – Quanta

2

VB.Net कोड आधारित कार्यान्वयन। मैंने बटन नियंत्रणों के लिस्टबॉक्स को पॉप्युलेट करने के लिए इसका इस्तेमाल किया। बटन नियंत्रण MEF एक्सटेंशन से बनाए जाते हैं। प्रत्येक एक्सटेंशन एक्सटेंशन के विवरण के लिए MEF की ExportMetaData विशेषता का उपयोग करता है। एक्सटेंशन VisiFire चार्टिंग ऑब्जेक्ट्स हैं। वांछित चार्ट निष्पादित करने के लिए उपयोगकर्ता बटन की सूची से चयनित एक बटन दबाता है।

 ' Create a ListBox of Buttons, one button for each MEF charting component. 
    For Each c As Lazy(Of ICharts, IDictionary(Of String, Object)) In ext.ChartDescriptions 
     Dim brdr As New Border 
     brdr.BorderBrush = Brushes.Black 
     brdr.BorderThickness = New Thickness(2, 2, 2, 2) 
     brdr.CornerRadius = New CornerRadius(8, 8, 8, 8) 
     Dim btn As New Button 
     AddHandler btn.Click, AddressOf GenericButtonClick 
     brdr.Child = btn 
     brdr.Background = btn.Background 
     btn.Margin = brdr.BorderThickness 
     btn.Width = ChartsLBx.ActualWidth - 22 
     btn.BorderThickness = New Thickness(0, 0, 0, 0) 
     btn.Height = 22 
     btn.Content = c.Metadata("Description") 
     btn.Tag = c 
     btn.ToolTip = "Push button to see " & c.Metadata("Description").ToString & " chart" 
     Dim lbi As New ListBoxItem 
     lbi.Content = brdr 
     ChartsLBx.Items.Add(lbi) 
    Next 

Public Event Click As RoutedEventHandler 

Private Sub GenericButtonClick(sender As Object, e As RoutedEventArgs) 
    Dim btn As Button = DirectCast(sender, Button) 
    Dim c As Lazy(Of ICharts, IDictionary(Of String, Object)) = DirectCast(btn.Tag, Lazy(Of ICharts, IDictionary(Of String, Object))) 
    Dim w As Window = DirectCast(c.Value, Window) 
    Dim cc As ICharts = DirectCast(c.Value, ICharts) 
    c.Value.CreateChart() 
    w.Show() 
End Sub 

<System.ComponentModel.Composition.Export(GetType(ICharts))> _ 
<System.ComponentModel.Composition.ExportMetadata("Description", "Data vs. Time")> _ 
Public Class DataTimeChart 
    Implements ICharts 

    Public Sub CreateChart() Implements ICharts.CreateChart 
    End Sub 
End Class 

Public Interface ICharts 
    Sub CreateChart() 
End Interface 

Public Class Extensibility 
    Public Sub New() 
     Dim catalog As New AggregateCatalog() 

     catalog.Catalogs.Add(New AssemblyCatalog(GetType(Extensibility).Assembly)) 

     'Create the CompositionContainer with the parts in the catalog 
     ChartContainer = New CompositionContainer(catalog) 

     Try 
      ChartContainer.ComposeParts(Me) 
     Catch ex As Exception 
      Console.WriteLine(ex.ToString) 
     End Try 
    End Sub 

    ' must use Lazy otherwise instantiation of Window will hold open app. Otherwise must specify Shutdown Mode of "Shutdown on Main Window". 
    <ImportMany()> _ 
    Public Property ChartDescriptions As IEnumerable(Of Lazy(Of ICharts, IDictionary(Of String, Object))) 

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