2013-12-10 3 views
1

첫 번째 Windows Phone 8 응용 프로그램에 설정 페이지를 추가하기 위해 MSDN 예제를 따르고 있습니다 (경고 - 완전히 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> 

을 추가 할 때까지 완벽하게 OK 렌더링 요소 "오류입니다. 리소스 절을 제거하면 오류가 사라지고 xaml이 렌더링되지만 물론 텍스트 상자 바인딩은 리소스를 볼 수 없기 때문에 모두 오류가 발생합니다.

나는 지난 3 시간 동안 인터넷 검색을 해왔고, 무엇이 잘못되었는지를 볼 수 없었고, 내가 본 곳과 다른 곳에서 발견 된 답변 중 어느 것도 적합하지 않은 것으로 보인다. 어떤 종류의 영혼이 내가 한 블론드 멍청한 일을 보여줄 수 있고 나를 비참함에서 벗어나게 할 수 있습니까?

편집 다음은 AppSettings 클래스입니다. 코드 숨김으로 해킹 된 Microsoft 코드 샘플 일뿐입니다.

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 클래스를 표시하십시오. :) 그리고 wobbler를 얻더라도 - 앱을 계속 실행할 수 있습니까? 당신은 재건, 폐쇄 및 솔루션/VS 열어 봤어? –

+0

문제는 동일한 UI (VisualTree)의 두 부분에서 UIElement를 다시 사용한다는 것입니다. AppSettings 클래스를 사용하여 이런 일이 발생하지 않을 수 있습니다. PLZ는 코드를 게시합니다. – atomaras

답변

1

코드가 매우 복잡합니다. 한 페이지 (AppApptings 클래스가 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

음, 클래스를 분리하고, 설정 페이지 클래스를 생성자로 축소하고, 새 AppSettingsImpl 클래스를 해당 페이지의 xaml에서 참조했습니다. 이제 최소한 코드가 정상적으로 실행됩니다. 근본적인 문제를 확인 했으니 답을 부르겠다. –

관련 문제