2013-12-10 67 views
1

我正在關注MSDN示例,以便將設置頁面添加到我的第一個Windows Phone 8應用程序(警告 - 我完全是XAML的新手,我是C++人員)。WP8 xaml導致「元素已經是另一個元素的子元素」

的XAML看起來是這樣的:

<phone:PhoneApplicationPage 
x:Class="PicoSDU.AppSettings" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" 
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone" 
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
xmlns:local="clr-namespace:PicoSDU" 
FontFamily="{StaticResource PhoneFontFamilyNormal}" 
FontSize="{StaticResource PhoneFontSizeNormal}" 
Foreground="{StaticResource PhoneForegroundBrush}" 
SupportedOrientations="Portrait" Orientation="Portrait" 
mc:Ignorable="d" 
shell:SystemTray.IsVisible="True"> 


<phone:PhoneApplicationPage.Resources> 
    <local:AppSettings x:Key="PicoSettings"></local:AppSettings> 
</phone:PhoneApplicationPage.Resources> 


<!--LayoutRoot is the root grid where all page content is placed--> 
<Grid x:Name="LayoutRoot" Background="Transparent"> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="Auto"/> 
     <RowDefinition Height="*"/> 
    </Grid.RowDefinitions> 

    <!--TitlePanel contains the name of the application and page title--> 
    <StackPanel Grid.Row="0" Margin="12,17,0,28"> 
     <TextBlock Text="PicoSDU" Style="{StaticResource PhoneTextNormalStyle}"/> 
     <TextBlock Text="Settings" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/> 
    </StackPanel> 

    <!--ContentPanel - place additional content here--> 
    <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> 


    <StackPanel Margin="30,0,0,0"> 
     <TextBlock Height="36" HorizontalAlignment="Left" Margin="0,0,0,0" Name="txtIpAddress" Text="IP Address" VerticalAlignment="Top" Width="169" /> 
     <TextBox Name="tbIpAddress" HorizontalAlignment="Left" Margin="0,0,0,0" VerticalAlignment="Top" Width="274" 
       Text="{Binding Source={StaticResource PicoSettings}, Path=IpSetting, Mode=TwoWay}"/> 
     <TextBlock Height="36" HorizontalAlignment="Left" Margin="0,0,0,0" Name="txtPort" Text="Port Number" VerticalAlignment="Top" Width="169" /> 
     <TextBox Name="tbPort" HorizontalAlignment="Left" Margin="0,0,0,0" VerticalAlignment="Top" Width="274" 
       Text="{Binding Source={StaticResource PicoSettings}, Path=PortSetting, Mode=TwoWay}"/> 
     <TextBlock Height="36" HorizontalAlignment="Left" Margin="0,0,0,0" Name="txtSysId" Text="System ID" VerticalAlignment="Top" Width="169" /> 
     <TextBox Name="tbSysId" HorizontalAlignment="Left" Margin="0,0,0,0" VerticalAlignment="Top" Width="274" 
       Text="{Binding Source={StaticResource PicoSettings}, Path=SysIdSetting, Mode=TwoWay}"/> 
     <TextBlock Height="36" HorizontalAlignment="Left" Margin="0,0,0,0" Name="txtWsId" Text="Station ID" VerticalAlignment="Top" Width="169" /> 
     <TextBox Name="tbWsId" HorizontalAlignment="Left" Margin="0,0,0,0" VerticalAlignment="Top" Width="274" 
       Text="{Binding Source={StaticResource PicoSettings}, Path=WsIdSetting, Mode=TwoWay}"/> 
    </StackPanel> 

    </Grid> 
</Grid> 

</phone:PhoneApplicationPage> 

所以,很簡單。四個文本框。它呈現完全確定,直到我只要我補充一點,XAML解析器拋出一個搖擺和根的PhoneApplicationPage變得彎彎曲曲的老藍和報告我們最喜愛的「元素已經是另一個孩子添加的資源條款

<phone:PhoneApplicationPage.Resources> 
    <local:AppSettings x:Key="PicoSettings"></local:AppSettings> 
</phone:PhoneApplicationPage.Resources> 

元素「錯誤。如果我刪除了資源子句,那麼該錯誤消失,並且xaml呈現,但是當然,文本框綁定會導致錯誤,因爲他們看不到它們的資源。

我一直在谷歌搜索這最後三個小時,我看不出有什麼問題,並沒有我在這裏和其他地方找到的答案似乎適合。一些善良的靈魂能否向我展示我所做的愚蠢愚蠢的事情,請把我從痛苦中解救出來?

編輯 這裏是AppSettings類。這只是微軟代碼示例,侵入代碼隱藏:

namespace PicoSDU 
{ 
public partial class AppSettings : PhoneApplicationPage 
{ 
    // Our settings 
    IsolatedStorageSettings settings; 

    // The key names of our settings 
    const string IpSettingKeyName = "IpSetting"; 
    const string SysIdSettingKeyName = "SysIdSetting"; 
    const string WsIdSettingKeyName = "WsIdSetting"; 
    const string PortSettingKeyName = "PortSetting"; 

    // The default value of our settings 
    const string IpSettingDefault = "81.179.24.51"; 
    const string SysIdSettingDefault = "1"; 
    const string WsIdSettingDefault = "511"; 
    const string PortSettingDefault = "1846"; 

    public AppSettings() 
    { 
     InitializeComponent(); 
     try 
     { 
      settings = IsolatedStorageSettings.ApplicationSettings; 
     } 
     catch (System.IO.IsolatedStorage.IsolatedStorageException e) 
     { 
      // handle exception 
     } 
    } 

    public bool AddOrUpdateValue(string Key, Object value) 
    { 
     bool valueChanged = false; 

     // If the key exists 
     if (settings.Contains(Key)) 
     { 
      // If the value has changed 
      if (settings[Key] != value) 
      { 
       // Store the new value 
       settings[Key] = value; 
       valueChanged = true; 
      } 
     } 
     // Otherwise create the key. 
     else 
     { 
      settings.Add(Key, value); 
      valueChanged = true; 
     } 
     return valueChanged; 
    } 

    public T GetValueOrDefault<T>(string Key, T defaultValue) 
    { 
     T value; 

     // If the key exists, retrieve the value. 
     if (settings.Contains(Key)) 
     { 
      value = (T)settings[Key]; 
     } 
     // Otherwise, use the default value. 
     else 
     { 
      value = defaultValue; 
     } 
     return value; 
    } 

    public void Save() 
    { 
     settings.Save(); 
    } 

    public string IpSetting 
    { 
     get 
     { 
      return GetValueOrDefault<string>(IpSettingKeyName, IpSettingDefault); 
     } 
     set 
     { 
      if (AddOrUpdateValue(IpSettingKeyName, value)) 
      { 
       Save(); 
      } 
     } 
    } 

    public string SysIdSetting 
    { 
     get 
     { 
      return GetValueOrDefault<string> (SysIdSettingKeyName, SysIdSettingDefault); 
     } 
     set 
     { 
      if (AddOrUpdateValue (SysIdSettingKeyName, value)) 
      { 
      Save(); 
      } 
     } 
    } 

    public string WsIdSetting 
    { 
     get 
     { 
      return GetValueOrDefault<string> (WsIdSettingKeyName, WsIdSettingDefault); 
     } 
     set 
     { 
      if (AddOrUpdateValue (WsIdSettingKeyName, value)) 
      { 
      Save(); 
      } 
     } 
    } 

    public string PortSetting 
    { 
     get 
     { 
      return GetValueOrDefault<string> (PortSettingKeyName, PortSettingDefault); 
     } 
     set 
     { 
      if (AddOrUpdateValue (PortSettingKeyName, value)) 
      { 
       Save(); 
      } 
     } 
    } 
} 
} 
+0

這是...奇怪。你可以發佈堆棧跟蹤,也許可以定義'AppSettings'類嗎? – McGarnagle

+0

是的,首先向我們展示AppSettings類:)即使你得到了搖擺 - 你還可以運行應用程序嗎?你有沒有嘗試重建,關閉和打開解決方案/ VS? –

+0

問題是UIElement在同一個UI(VisualTree)的兩部分中被重用。我不知道如何使用你的AppSettings類來實現。 Plz發佈其代碼。 – atomaras

回答

1

您的代碼是相當bizzare。您正嘗試將一個Page(您的AppSettings類從PhoneApplicationPage繼承)嵌入到另一個頁面中。更好的方法是使用MVVM模式。

請勿使AppSettings從PhoneApplicationPage繼承並將其設置爲ViewModel。更多信息在http://msdn.microsoft.com/en-us/library/windowsphone/develop/gg521153(v=vs.105).aspx

+0

這是問題的一部分。在Microsoft示例中,AppSettings類不是從PhoneApplicationPage派生的,但該示例沒有解釋如何創建實際設置頁面並將其鏈接到AppSettings類。將AppSettings類放在頁面代碼中看起來像是一個嚮導,可以解決這個問題,但顯然不是。如果你是一個老C++的人,這是所有的__very__不同。 –

+0

嗯,我把這個類分開了,將Settings頁面類減少爲一個構造函數,並從該頁的xaml引用了新的AppSettingsImpl類,現在至少代碼運行OK。我想你已經確定了潛在的問題,所以我會把它稱爲回答。 –

相關問題