其它namespace的代碼訪問控件時會出現這個問題app
須要把控件狀態由protected改成publicide
<TextBlock x:FieldModifier="public" x:Name="AccessibleTextBlock" />
The x:Name attribute in XAML creates named fields that you can use to access the controls from the code-behind. However, as opposed to WPF, in UWP these fields are private which means you can access them from the code-behind only, not from other classes. While noting it is a good idea from architectural standpoint, is it possible to change this behavior?ui
Let’s define a simple TextBlock
control in XAML.this
1
|
<TextBlock x:Name="InaccessibleTextBlock" />
|
Now, what happens if we create a new class that takes the page as parameter of one of the methods and tries to access the TextBlock
?idea
1
2
3
4
5
6
7
|
public static class OutsideAccess
{
public static void ChangeTexts(MainPage page)
{
page.InaccessibleTextBlock.Text = "Accessed"; //does not work!
}
}
|
The app will not compile, because the field is inaccessible due to its protection level.spa
To see what actually happens behind the scenes, let’s open the auto-generated MainPage.g.i.cs file which can be found in the obj folder. We can find the following field there:code
1
2
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Windows.UI.Xaml.Build.Tasks"," 14.0.0.0")]
private global::Windows.UI.Xaml.Controls.TextBlock InaccessibleTextBlock;
|
Clearly, the field is defined as private.orm
To change the code generation behavior, you can use the x:FieldModifier
directive. This allows you to specify excatly which access modifier should be field have.blog
1
|
<TextBlock x:FieldModifier="public" x:Name="AccessibleTextBlock" />
|
Now, accessing the field from the outside works as a charm:seo
1
2
3
4
5
6
7
|
public static class OutsideAccess
{
public static void ChangeTexts(MainPage page)
{
page.AccessibleTextBlock.Text = "Accessed";
}
}
|
Note that you are not limited to public
and private
only, and you can also set the field to be internal
or protected
.
We can confirm the change of visiblity was reflected in the generated source code:
1
2
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Windows.UI.Xaml.Build.Tasks"," 14.0.0.0")]
public global::Windows.UI.Xaml.Controls.TextBlock AccessibleTextBlock;
|
If you wonder, what is the default behavior in WPF, wonder no more!
WPF’s convention is to set all named fields as internal
by default:
1
2
|
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
internal System.Windows.Controls.TextBlock InaccessibleTextBlock;
|
You can use the x:FieldModifier
directive to modify the visibility the same way as in UWP.