2012-04-06 5 views
22

मेरे पास एक WPF नियंत्रण लाइब्रेरी है जिसे विंडोज़ फॉर्म एप्लिकेशन में जोड़ा जा रहा है। हम नियंत्रण को स्थानीयकरण योग्य होने की अनुमति देना चाहते हैं, हालांकि मुझे यकीन नहीं है कि कोड को डुप्लिकेट किए बिना इसे पूरी तरह से कैसे पूरा किया जाए। This is what I am doing nowक्या एक WPF नियंत्रण लाइब्रेरी में StaticResource का उपयोग करने का कोई तरीका है और डिज़ाइन-टाइम पर देखने में सक्षम है?

असल में, विंडोज़ ऐप में, मुख्य एप्लिकेशन को बंद करने से पहले, मैं ऐप.एक्सएएमएल को तत्काल बना रहा हूं जो फॉर्म ऐप के भीतर रहता है (मेरे संसाधनों के लिए मेरे लिंक जो फॉर्म एप के भीतर भी रहते हैं)। यह रनटाइम के लिए पूरी तरह से काम करता है।

हालांकि, मेरे उपयोगकर्ता नियंत्रण में Content="{StaticResource SomeVariableName}" है, जो खाली होने पर समाप्त होता है। मैं इसे अपने नियंत्रण पुस्तकालय में app.xaml और उचित संसाधन शब्दकोश रखने के द्वारा ठीक कर सकता हूं जो मेरे विंडोज़ फॉर्म ऐप से मेल खाता है। हालांकि, यह डुप्लिकेट कोड है।

बातें मैं पहले से ही कोई फायदा नहीं हुआ है:

  • App.xaml कि मेरी रूपों अनुप्रयोग के भीतर से उपयोगकर्ता नियंत्रण पुस्तकालय के अंदर रहता है इन्स्तांत। यह काम नहीं करता है क्योंकि मेरे संसाधनों के लिए यूआरआई एक एम्बेडेड संसाधन की तलाश में है, न कि मेरे स्थानीय संसाधन शब्दकोश (मैं बस संसाधन फ़ाइलों को नियंत्रण से अपने फॉर्म ऐप के भीतर एक उचित स्थान पर कॉपी कर सकता हूं)। क्या मैं यहां DeferrableContent का लाभ उठा सकता हूं? जहां तक ​​मुझे इस विशेषता पर और ऑनलाइन इसका उपयोग कैसे किया जाना चाहिए, वहां बहुत अधिक ऑनलाइन नहीं है।
  • मैं ऐप और शब्दकोश दोनों के लिए पोस्ट बिल्ड का उपयोग करना चाहता हूं, हालांकि, ऐप इंस्टेंटेशन एक संकलित App.xaml का एक स्थिर संदर्भ है जहां तक ​​मैं कह सकता हूं। तो, App.xaml प्रपत्र के भीतर रहते हैं
    • कम से कम मैं एक पोस्ट का निर्माण resourcedictionary.xaml चलती के साथ एक दोहराया App.xaml की कोशिश किया जाना चाहिए। मुझे लगा कि एक डुप्लिकेट ऐप.एक्सएएमएल ठीक है क्योंकि यह चालक बल है और हो सकता है कि आप किसी भी नियंत्रण से किसी पर भरोसा नहीं करना चाहें (जो वापस सर्किल करता है और आपको आश्चर्य होता है कि क्या आपके पास नियंत्रण में App.xaml होना चाहिए सब? जब तक आप एम्बेडेड संसाधनों का उपयोग करने वाले डिफ़ॉल्ट को अनुमति नहीं देना चाहते हैं ....) यह भी असफल रहा कि यह संसाधन नहीं मिला है, भले ही यह रखा गया था जहां यूआरआई को इंगित करना चाहिए था। Uri resourceLocater = new Uri("/WindowsFormsApplication3;component/app.xaml", UriKind.Relative);

तो करने के लिए decompiled कोड अंक, वहाँ काम करते हैं और घटक चूक के डिजाइन समय को देखने की है और दोहराव से बचने के लिए इस के लिए अनुमति देने के लिए कोई तरीका है? या, इस मामले में नकल ठीक है? यदि मेरी दूसरी बुलेट की उप-वस्तु ठीक लगती है (नकल किए गए App.xaml को प्रतिलिपि बनाई गई पुनर्वितरण के साथ), मैं इसे घटक स्तर आइटम की तलाश कैसे नहीं कर सकता, बल्कि इसके बजाय फ़ाइल स्तर एक?

अंतिम प्रश्न (और यदि आवश्यक हो तो मैं इसे अलग से पोस्ट कर सकता हूं) कि मैंने अभी ध्यान दिया है। मेरा App.xaml कोड में बनाया जा रहा है, जिससे मुझे फ्लाई पर नए संसाधन शब्दकोश बनाने की अनुमति नहीं मिलती है। क्या इसे करने का कोई तरीका है?

अंतिम विकल्प ... संभवतः सबसे अच्छा विकल्प? - I plan on using Andre van Heerwaarde's code anyway, तो क्या मुझे सिर्फ फाइल के अस्तित्व की जांच करनी चाहिए और इसे फ्लाई पर मर्ज किए गए संसाधन के रूप में जोड़ना चाहिए? असल में, मेरे उपयोगकर्ता नियंत्रण में एक App.xaml है जो एक डिफ़ॉल्ट एम्बेडेड संसाधन डिक्शनरी से लिंक है। और, फिर कोड फ्लाई पर उपयुक्त स्थानीय संसाधनों के लिए देखो, जो सापेक्ष फ़ाइल पथ हो सकता है? यहां केवल एकमात्र नकारात्मकता यह है कि फ्लाई पर डिफॉल्ट को बदला नहीं जा सकता है ... जिसे मैं शायद किसी निर्दिष्ट स्थान (कुछ प्रकार के सम्मेलन का उपयोग करके) में देख सकता हूं और क्या इसे अंतर्निहित एक पर पसंद किया है?

ओह, और एम्बेडेड संसाधनों को न चाहने का मेरा कारण यह है कि अंतिम उपयोगकर्ता बिल्ड किए जाने के बाद नए स्थानीय संसाधनों को जोड़/संशोधित कर सकते हैं।

मैं कोड जोड़ सकता हूं अगर यह आपको बेहतर तरीके से देखने में मदद करेगा, बस मुझे बताएं।

अद्यतन

मैं अब स्टाइल के साथ एक आगे समस्या में चल रहा हूँ और सिर्फ स्थानीयकृत नहीं।

<Button Style="{StaticResource GrayButton}" 

कुछ और बातें मैंने कोशिश की/सोचा:

  • मैं एक App.xaml नहीं बना सकते हैं (कि

    यहाँ नियंत्रणों में से एक पर आंतरिक बटनों में से एक का एक उदाहरण है कभी भी इस्तेमाल नहीं किया जाएगा) पुस्तकालय परियोजनाओं में अनुप्रयोग परिभाषाओं के रूप में स्थापित संसाधन डिक्शनरी के साथ स्थापित नहीं किया गया है। मैं इसे नियंत्रण के संसाधनों में एम्बेड कर सकता हूं, लेकिन फिर हमेशा किसी भी अनुप्रयोग स्तर संसाधनों पर प्राथमिकता लेनी होगी और मैं अनुकूलन खो देता हूं।

Here is a connect case है कि वास्तव में, मैं के लिए क्या देख रहा हूँ की तरह लगता है, लेकिन यह (परे top..which काम नहीं करता है) कि मुझे लगता है कि के बारे में सोच सकते हैं कि इस

समाधान के लिए किसी भी वास्तविक समाधान प्रदान नहीं करता है काम कर सकता है (और अभी तक कोशिश करने के लिए) कुछ ऐसा काम करने के लिए भी लगता है जो मुझे लगता है कि सरल होना चाहिए। लेकिन, मैं उस नियंत्रण में कुछ निर्भरता गुणों को बनाने में सक्षम हो सकता हूं जिन्हें मैं बांध सकता हूं और फिर उन परियोजनाओं को ओवरराइड करने की अनुमति देता हूं जो नियंत्रण का उपयोग करेंगे। जैसा कि मैंने कहा, यह एक बहुत ही सरल अनुरोध के लिए बहुत सारे काम की तरह लगता है :)। क्या यह भी काम करेगा? और सबसे महत्वपूर्ण बात यह है कि क्या एक बेहतर, सरल समाधान है जिसे मैं याद कर रहा हूं?

उत्तर

12

मैं इस समस्या में एक बार दौड़े हैं कहा जाता है, और मैं छोड़ने पूरी बात "संसाधन विहित शब्दकोशों में महत्वपूर्ण द्वारा अनुक्रमित वस्तुओं रहे हैं" द्वारा यह संकल्प लिया।

मेरा मतलब है, एक परियोजना में संसाधन को परिभाषित करने और इसे "कुंजी" द्वारा दूसरे में संदर्भित करने का सरल तथ्य किसी भी साधु व्यक्ति को हंसबंप देना चाहिए। मैं मजबूत संदर्भ चाहता था।

इस समस्या का समाधान मेरे एक custom tool कि प्रत्येक संसाधन के लिए एक संपत्ति के साथ स्थिर वर्गों के लिए मेरी संसाधन XAML फ़ाइलों में कनवर्ट करता है बनाने के लिए किया गया था:

तो MyResources.xaml:

<ResourceDictionary> 
    <SolidColorBrush x:Key="LightBrush" ... /> 
    <SolidColorBrush x:Key="DarkBrush" ... /> 
</ResourceDictionary> 

हो जाता है MyResources.xaml .cs

public static class MyResources { 

    static MyResources() { 
    // load the xaml file and assign values to static properties 
    } 

    public static SolidColorBrush LightBrush { get; set; } 
    public static SolidColorBrush DarkBrush { get; set; } 

} 

एक संसाधन संदर्भित के लिए, आप x:StaticStaticResource के बजाय का उपयोग कर सकते हैं:

<Border 
    Fill="{x:Static MyResources.LightBrush}" 
    BorderBrush="{x:Static MyResources.DarkBrush}" 
    ... /> 

अब आपको मजबूत संदर्भ, स्वत: पूर्णता और संकलन समय संसाधनों की जांच मिली है।

+1

+1 यह अब तक का सबसे अच्छा जवाब है जिसे मैंने वास्तव में देखा है। ऐसा करके, मैं अपना संसाधन कोड कहीं भी डाल सकता हूं, और इसे कार्य कर सकता हूं हालांकि मुझे इसे कार्य करने की आवश्यकता है। लेकिन, यह डिजाइनर में कैसे काम करेगा? क्या यह MyResources का एक उदाहरण नया होगा और डिफ़ॉल्ट का उपयोग करेगा? –

+0

जहां तक ​​मुझे याद है, हाँ। –

+0

+1 शानदार!इस तरह से संपर्क करने के लिए कभी भी मेरे दिमाग को पार नहीं किया! – Dom

0

मुझे स्टाइलिंग थीम्स और उपलब्ध स्थिर संसाधनों से निपटने में भी समस्या थी। इसलिए, मैंने एक स्टैंड-अलोन लाइब्रेरी बनाई जिसकी मूल रूप से थीम के अलावा कुछ भी नहीं था, जो आपके पूर्व जुड़े प्रश्न के आपके मर्ज किए गए संसाधनों की तरह घोंसला हुआ था।

फिर, विंडोज फार्म (.xaml) में, मैं सिर्फ कुछ है कि पुस्तकालय के संदर्भ में, जैसे

<Window x:Class="MyAppNamespace.MyView" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" ... /> 

    <Window.Resources> 
    <ResourceDictionary> 
     <ResourceDictionary.MergedDictionaries> 
     <!-- Common base theme --> 
     <ResourceDictionary Source="pack://application:,,,/MyLibrary;component/Themes/MyMainThemeWrapper.xaml" /> 
     </ResourceDictionary.MergedDictionaries> 
     </ResourceDictionary> 
    </Window.Resources> 

    <Rest of XAML for the WPF window> 

</Window> 

"घटक" डाल दिया "MyLibrary" परियोजना की जड़ का उल्लेख करने के लिए प्रकट होता है। वास्तविक प्रोजेक्ट में, मैंने "थीम्स" नामक सबफ़ोल्डर बनाया, इसलिए स्रोत में शामिल है ...; घटक/थीम्स/...

"MyMainThemeWrapper.xaml" आपके नेस्टेड मर्ज किए गए संसाधन शब्दकोशों की तरह बहुत अधिक है, और यह सब कुछ अन्य पुस्तकालयों से पूरी तरह से देखता है।

+0

जो डिज़ाइनटाइम पर मेरे UserControl में प्रचार नहीं करेगा, हालांकि। और, भले ही मैंने अपने UserControl में संसाधन शब्दकोश लाइब्रेरी का संदर्भ दिया हो, फिर भी वह UserControl में एम्बेड किया जाएगा। मुझे प्रश्न को थोड़ा स्पष्ट करने की आवश्यकता हो सकती है, लेकिन मुझे कुछ ऐसी चीज चाहिए जो डिज़ाइन (डिफ़ॉल्ट) पर काम की जा सके, जिसे रनटाइम पर ओवरराइड किया जा सकता है (एक सामग्री resourcedictionary.xaml, एम्बेडेड नहीं) –

0

यहां मेरी समस्या के लिए आंशिक समाधान है। मैंने ढीले संसाधनों को संभालने की कोशिश नहीं की है, लेकिन मुझे WinForms और WPF के बीच संसाधन साझा करने में कुछ सफलता मिली है।

  • अपने संसाधनों को रखने के लिए क्लास लाइब्रेरी बनाएं। Reses फ़ाइलों (उदा। Resources.resx, Resources.fr।resx, आदि)
  • अपने WinForms Infralution.Localization.Wpf मार्कअप विस्तार और संस्कृति प्रबंधक, उदा का उपयोग कर WPF से की मेजबानी
  • संदर्भ अपने संसाधन पुस्तकालय में संसाधनों बनाएँ WPF उपयोगकर्ता नियंत्रण पुस्तकालय

  • में अपने WPF नियंत्रण बनाएं

    <TextBlock Text="{Resx ResxName=ResourceLib.Resources, Key=Test}"/> 
    
  • नियंत्रण टेम्पलेट्स, ई के रूप में एक या अधिक संसाधन शब्दकोशों, जी में अपने WPF उपयोगकर्ता नियंत्रण की सामग्री रखो

    <ControlTemplate x:Key="TestTemplate"> 
        <Grid> 
         <Grid.RowDefinitions> 
          <RowDefinition/> 
          <RowDefinition/> 
         </Grid.RowDefinitions> 
    
         <TextBlock Text="{Resx ResxName=ResourceLib.Resources, Key=Test}"/> 
        </Grid> 
    </ControlTemplate> 
    
  • उपयोग अपने उपयोगकर्ता में संसाधन टेम्पलेट को नियंत्रित करता है

    <UserControl x:Class="WpfControls.UserControl1" 
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
          xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
          xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d" 
          d:DesignHeight="300" d:DesignWidth="300" > 
        <UserControl.Resources> 
         <ResourceDictionary> 
          <ResourceDictionary.MergedDictionaries> 
           <ResourceDictionary Source="ResourceDictionary.xaml"/> 
          </ResourceDictionary.MergedDictionaries> 
         </ResourceDictionary> 
        </UserControl.Resources> 
        <ContentControl Template="{StaticResource TestTemplate}" /> 
    </UserControl> 
    
  • चीजें काम करने के लिए कोड की कुछ पंक्तियां जोड़ें

    public partial class UserControl1 : UserControl 
    { 
        // we require a reference to the resource library to ensure it's loaded into memory 
        private Class1 _class1 = new Class1(); 
    
        public UserControl1() 
        { 
         // Use the CultureManager to switch to the current culture 
         CultureManager.UICulture = Thread.CurrentThread.CurrentCulture; 
    
         InitializeComponent(); 
        } 
    } 
    

यहाँ एक सरल demo app WindowsFormsHost.7z

+0

यह कैसे अलग है क्या @DRapp सुझाव दिया? –

+0

ठीक है, मैं आपके UserControl में ContentControl डालकर 'Content = "{StaticResource SomeVariableName}" समस्या को ठीक करता हूं, app.xaml के साथ कोई गड़बड़ नहीं करता है। UserControl स्थानीयकरण योग्य है और WinForms के साथ संसाधन संसाधन साझा करता है। Resx फ़ाइलों का उपयोग कर। यह वही कैसे है? – Phil

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

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