2010-02-06 14 views
5

मैं स्कूल के लिए एक सरल टिक टैक पैर की अंगुली खेल लिख रहा हूँ। असाइनमेंट सी ++ में है, लेकिन शिक्षक ने मुझे चुनौती के रूप में सी # और डब्ल्यूपीएफ का उपयोग करने की अनुमति दी है। मुझे सभी गेम लॉजिक समाप्त हो गए हैं और फॉर्म ज्यादातर पूरा हो गया है, लेकिन मैंने दीवार में भाग लिया है। मैं वर्तमान में एक Label उपयोग कर रहा हूँ कौन है यह है बारी से संकेत मिलता है, और मैं इसे बदलने के लिए जब एक खिलाड़ी एक वैध कदम बनाता है चाहता हूँ। Applications = Code + Markup के अनुसार, मैं Window वर्ग के FindName विधि का उपयोग करने में सक्षम होना चाहिए। हालांकि, यह null लौटता रहता है। यहां कोड है:FindName लौटने अशक्त

public TicTacToeGame() 
{ 
    Title = "TicTacToe"; 
    SizeToContent = SizeToContent.WidthAndHeight; 
    ResizeMode = ResizeMode.NoResize; 

    UniformGrid playingField = new UniformGrid(); 
    playingField.Width = 300; 
    playingField.Height = 300; 
    playingField.Margin = new Thickness(20); 

    Label statusDisplay = new Label(); 
    statusDisplay.Content = "X goes first"; 
    statusDisplay.FontSize = 24; 
    statusDisplay.Name = "StatusDisplay"; // This is the name of the control 
    statusDisplay.HorizontalAlignment = HorizontalAlignment.Center; 
    statusDisplay.Margin = new Thickness(20); 

    StackPanel layout = new StackPanel(); 
    layout.Children.Add(playingField); 
    layout.Children.Add(statusDisplay); 

    Content = layout; 

    for (int i = 0; i < 9; i++) 
    { 
     Button currentButton = new Button(); 
     currentButton.Name = "Space" + i.ToString(); 
     currentButton.FontSize = 32; 
     currentButton.Click += OnPlayLocationClick; 

     playingField.Children.Add(currentButton); 
    } 

    game = new TicTacToe.GameCore(); 
} 

void OnPlayLocationClick(object sender, RoutedEventArgs args) 
{ 
    Button clickedButton = args.Source as Button; 

    int iButtonNumber = Int32.Parse(clickedButton.Name.Substring(5,1)); 
    int iXPosition = iButtonNumber % 3, 
     iYPosition = iButtonNumber/3; 

    if (game.MoveIsValid(iXPosition, iYPosition) && 
     game.Status() == TicTacToe.GameCore.GameStatus.StillGoing) 
    { 
     clickedButton.Content = 
      game.getCurrentPlayer() == TicTacToe.GameCore.Player.X ? "X" : "O"; 
     game.MakeMoveAndChangeTurns(iXPosition, iYPosition); 

     // And this is where I'm getting it so I can use it. 
     Label statusDisplay = FindName("StatusDisplay") as Label; 
     statusDisplay.Content = "It is " + 
      (game.getCurrentPlayer() == TicTacToe.GameCore.Player.X ? "X" : "O") + 
      "'s turn"; 
    } 
} 

यहां क्या हो रहा है? मैं दोनों जगहों पर एक ही नाम का उपयोग कर रहा हूं, लेकिन FindName इसे नहीं ढूंढ सकता। मैंने पदानुक्रम देखने के लिए स्नूप का उपयोग करने का प्रयास किया है, लेकिन फॉर्म से चुनने के लिए एप्लिकेशन की सूची में दिखाई नहीं देता है। मैंने स्टैक ओवरफ्लो पर खोज की और मुझे should be able to use VisualTreeHelper class मिला, लेकिन मुझे समझ में नहीं आता कि इसका उपयोग कैसे किया जाए।

कोई भी विचार?

उत्तर

6

FindName बुला नियंत्रण से XAML namescope पर चल रही है। आपके मामले में, के बाद से नियंत्रण पूरी तरह से कोड के भीतर बनाई गई है, कि XAML namescope खाली है - और यही कारण है FindName विफल रहता है। this page देखें: प्रारंभिक लदान और प्रसंस्करण के बाद तत्व पेड़ से

किसी भी अतिरिक्त वर्ग कि XAML namescope को परिभाषित करता है के लिए RegisterName के उचित कार्यान्वयन कॉल करना होगा। अन्यथा, अतिरिक्त वस्तु को नाम से संदर्भित नहीं किया जा सकता है जैसे FindName। केवल नाम संपत्ति (या x: नाम विशेषता) को सेट करना उस नाम को किसी भी XAML नेमस्कोप में पंजीकृत नहीं करता है।

आपकी समस्या को ठीक करने का सबसे आसान तरीका कक्षा में अपने स्थिति डिस्प्ले लेबल को एक निजी सदस्य के रूप में संदर्भित करना है। या, यदि आप कैसे VisualTreeHelper वर्ग का उपयोग करने के सीखना चाहते हैं, वहाँ एक कोड स्निपेट at the bottom of this page कि दृश्य पेड़ मिलान तत्व को खोजने के लिए चलता है।

(संपादित: बेशक, यह कम काम करते हैं, VisualTreeHelper उपयोग करने के लिए यदि आप लेबल के लिए एक संदर्भ स्टोर करने के लिए नहीं करना चाहते हैं की तुलना में RegisterName कॉल करने के लिए है।)

मैं में पहली कड़ी पढ़ने की सलाह देते हैं अगर आप किसी भी गहराई में डब्ल्यूपीएफ/सिल्वरलाइट का उपयोग करने की योजना बनाते हैं तो इसकी पूरी तरह से। उपयोगी जानकारी है।

NameScope.SetNameScope(this, new NameScope()); 

तो फिर तुम खिड़की के साथ अपने लेबल का नाम रजिस्टर:

RegisterName(statusDisplay.Name, statusDisplay); 

तो यह सब आप सब करने की ज़रूरत हो रहा है

+0

मैंने इस कार्यक्रम के लिए निजी सदस्य के साथ जाने के लिए चुना है। स्पष्टीकरण के लिए धन्यवाद, मैं जितनी जल्दी हो सके पूरा पृष्ठ पढ़ूंगा। –

2

आप अपने खिड़की के लिए एक नया NameScope बनाने के लिए FindName() काम करने के लिए।

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