كيف يمكنني إضافة مسار ، تم تعريفه في موارد XAML ، عدة مرات إلى نموذج WPF في وقت التشغيل؟

StackOverflow https://stackoverflow.com/questions/1377658

سؤال

لدي مسار محدد في XAML:

<UserControl.Resources>
    <ResourceDictionary>
        <Path x:Key="N44" Width="20" Height="80" Stretch="Fill" Fill="#FF000000" Data="M 20,25.2941L 20,29.4118L 15.9091,29.4118L 15.9091,40L 12.2727,40L 12.2727,29.4118L 2.54313e-006,29.4118L 2.54313e-006,25.6985L 13.4872,7.62939e-006L 15.9091,7.62939e-006L 15.9091,25.2941L 20,25.2941 Z M 12.2727,25.2941L 12.2727,5.28493L 2.09517,25.2941L 12.2727,25.2941 Z M 20,65.2941L 20,69.4118L 15.9091,69.4118L 15.9091,80L 12.2727,80L 12.2727,69.4118L -5.08626e-006,69.4118L -5.08626e-006,65.6985L 13.4872,40L 15.9091,40L 15.9091,65.2941L 20,65.2941 Z M 12.2727,65.2941L 12.2727,45.2849L 2.09517,65.2941L 12.2727,65.2941 Z "/>
    </ResourceDictionary>
</UserControl.Resources>

أرغب في إضافته إلى wpf gird والقيام بذلك مرة واحدة مثل هذا يعمل:

System.Windows.Shapes.Path aPath = new System.Windows.Shapes.Path();
aPath = (System.Windows.Shapes.Path)this.Resources["N44"];
LayoutRoot.Children.Add(aPath); 

ومع ذلك ، إذا قمت بإضافة هذا الرمز على زر انقر فوق الحدث ثم انقر فوق الزر مرتين ، فسيتم إلقاء خطأ يوضح

"المرئي المحدد هو بالفعل طفل من مرئي آخر أو جذر تكوين تكوين."

حاولت بعد ذلك إنشاء حالتين من المورد ، لكنني واصلت تلقي نفس الخطأ. فيما يلي الرمز الذي استخدمته لهذا الاختبار:

private void cmbTest_Click(object sender, System.Windows.RoutedEventArgs e)
  {
   System.Windows.Shapes.Path aPath = new System.Windows.Shapes.Path();
   aPath = (System.Windows.Shapes.Path)this.Resources["N44"];

   if (LayoutRoot.Children.Contains(aPath) == true){
    System.Windows.Shapes.Path bPath = (System.Windows.Shapes.Path)this.Resources["N44"];
    LayoutRoot.Children.Add(bPath); 
   }else{
    aPath.Name = "a";
    aPath.Tag = "a";
    LayoutRoot.Children.Add(aPath);
   }
  }

على هذا النحو ، كيف يمكنني إضافة مسار XAML ، والذي تم تعريفه في الموارد ، عدة مرات إلى نموذج WPF في وقت التشغيل؟

هل كانت مفيدة؟

المحلول 2

لقد وجدت منذ ذلك الحين أنني فاتني جزء مهم من وثائق من MSDN:

الأنواع القابلة للمشاركة وأنواع uielement:

قاموس الموارد هو تقنية لتحديد أنواع وقيم هذه الأنواع في XAML. ليست كل الأنواع أو القيم مناسبة للاستخدام من موارد الموارد. لمزيد من المعلومات حول الأنواع التي تعتبر قابلة للمشاركة في Silverlight ، راجع قواميس الموارد.

على وجه الخصوص ، لا يتم مشاركة جميع الأنواع المشتقة من UiElement إلا إذا كانت تأتي من قوالب وتطبيق قالب على مثيل تحكم محدد. باستثناء حالة القالب ، من المتوقع أن يوجد uielement فقط في مكان واحد في شجرة كائن بمجرد إنشاء مثيل له ، ومن المحتمل أن ينتهك هذا المبدأ.

الذي سألخصه ، هذه ليست الطريقة التي تعمل بها لا يقوم بإنشاء مثيل جديد في كل مرة أقوم فيها بتنفيذ هذا الرمز - إنه ينشئ فقط مرجعًا إلى الكائن - وهذا هو السبب في أنه يعمل مرة واحدة ولكن ليس عدة مرات. لذلك بعد قراءة المزيد ، توصلت إلى 3 طرق محتملة لحل مشكلتي.

1) استخدم تقنية لإنشاء نسخة عميقة لكائن جديد. مثال من سؤال stackoverflow الآخر - كائنات استنساخ عميقة

2) قم بتخزين XAML في الأوتار داخل التطبيق ثم استخدم قارئ XAML لإنشاء مثيلات من المسارات:

System.Windows.Shapes.Path newPath = (System.Windows.Shapes.Path)System.Windows.Markup.XamlReader.Parse("<Path xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'  Width='20' Height='80' Stretch='Fill' Fill='#FF000000' Data='M 20,25.2941L 20,29.4118L 15.9091,29.4118L 15.9091,40L 12.2727,40L 12.2727,29.4118L 2.54313e-006,29.4118L 2.54313e-006,25.6985L 13.4872,7.62939e-006L 15.9091,7.62939e-006L 15.9091,25.2941L 20,25.2941 Z M 12.2727,25.2941L 12.2727,5.28493L 2.09517,25.2941L 12.2727,25.2941 Z M 20,65.2941L 20,69.4118L 15.9091,69.4118L 15.9091,80L 12.2727,80L 12.2727,69.4118L -5.08626e-006,69.4118L -5.08626e-006,65.6985L 13.4872,40L 15.9091,40L 15.9091,65.2941L 20,65.2941 Z M 12.2727,65.2941L 12.2727,45.2849L 2.09517,65.2941L 12.2727,65.2941 Z ' HorizontalAlignment='Left' VerticalAlignment='Top' Margin='140,60,0,0'/>");
LayoutRoot.Children.Add(newPath);

3) تخزين بيانات المسار فقط في قاموس الموارد. قم بإنشاء مثيل جديد للمسار في التعليمات البرمجية ، وقم بتطبيق بيانات المسار على المسار الجديد ، ثم أضف الخصائص الأخرى التي أهتم بها يدويًا.

XAML - يتم تخزين بيانات المسار كقياس تدفق:

<UserControl.Resources>
    <ResourceDictionary>
        <StreamGeometry x:Key="N44">M 20,25.2941L 20,29.4118L 15.9091,29.4118L 15.9091,40L 12.2727,40L 12.2727,29.4118L 2.54313e-006,29.4118L 2.54313e-006,25.6985L 13.4872,7.62939e-006L 15.9091,7.62939e-006L 15.9091,25.2941L 20,25.2941 Z M 12.2727,25.2941L 12.2727,5.28493L 2.09517,25.2941L 12.2727,25.2941 Z M 20,65.2941L 20,69.4118L 15.9091,69.4118L 15.9091,80L 12.2727,80L 12.2727,69.4118L -5.08626e-006,69.4118L -5.08626e-006,65.6985L 13.4872,40L 15.9091,40L 15.9091,65.2941L 20,65.2941 Z M 12.2727,65.2941L 12.2727,45.2849L 2.09517,65.2941L 12.2727,65.2941 Z</StreamGeometry>
    </ResourceDictionary>
</UserControl.Resources>

رمز C# بعد ذلك إنشاء مثيل وتطبيق القيم الأخرى:

System.Windows.Shapes.Path bPath = new System.Windows.Shapes.Path();
bPath.Data = (System.Windows.Media.Geometry)this.FindResource("N44");

bPath.Width = 20;
bPath.Height = 80;

bPath.VerticalAlignment = System.Windows.VerticalAlignment.Top;
bPath.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;

left = left + 40;

System.Windows.Thickness thickness = new System.Windows.Thickness(left,100,0,0);
bPath.Margin = thickness;

bPath.Fill = System.Windows.Media.Brushes.Black;
LayoutRoot.Children.Add(bPath);

نصائح أخرى

هناك طريقة أسهل ومضمنة للقيام بذلك. SET X: Shared = "false" على المورد. سيسمح ذلك بإعادة استخدامه. ثم استخدمه عدة مرات كما تريد.

<UserControl.Resources>
    <ResourceDictionary>
        <Path x:Shared="False" x:Key="N44" Width="20" Height="80" Stretch="Fill" Fill="#FF000000" Data="..."/>
    </ResourceDictionary>
</UserControl.Resources>

مجرد إنشاء نمط للمسار ، وتطبيقه.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top