tutorial example c# winrt-xaml uwp

c# - example - ¿Por qué no puedo usar{x: vincular{RelativeSource Self}} en una plantilla de datos?



uwp tutorial (2)

Aunque parece que ha resuelto su problema, aún quiero hacer algunas aclaraciones para evitar confusiones y dejarlo claro para los lectores futuros.

Como ha mencionado @Peter Duniho, {x:Bind} no puede funcionar con la propiedad DataContext y {x:Bind} no tiene una propiedad de Source , por lo que no puede usar StaticResource como contexto de datos en {x:Bind} , pero puede usar una propiedad o una ruta estática en su lugar. Al usar {x:Bind} , usa la clase de fondo como su contexto de datos. Por ejemplo, cuando establece ItemsSource="{x:Bind NewsItems, Mode=OneWay}" , usa la clase XBindTest5.MainPage como su contexto de datos y vincula la propiedad NewsItems de esta clase a ItemsSource . Y mientras está dentro de un DataTemplate, {x:Bind} usa la clase declarada en x:DataType como su contexto de datos. Tenga en cuenta la siguiente explicación en DataTemplate yx: DataType :

Dentro de un DataTemplate (ya sea como plantilla de elemento, plantilla de contenido o plantilla de encabezado), el valor de Path no se interpreta en el contexto de la página, sino en el contexto del objeto de datos que se está modelando. Para que sus enlaces puedan ser validados (y se genere código eficiente para ellos) en tiempo de compilación, un DataTemplate necesita declarar el tipo de su objeto de datos usando x: DataType .

En su caso, utiliza el Command en DataTemplate , por lo que puede agregar una propiedad NewsItem en NewsItem y vincular esta propiedad a Command para usarla.

En su código subyacente:

public class NewsItem { public string Title { get; set; } public OpenItemCommand OpenCommand { get; set; } }

En el XAML:

<DataTemplate x:DataType="local:NewsItem"> <StackPanel> <Button Command="{x:Bind OpenCommand}" CommandParameter="{x:Bind}"> <TextBlock Text="{x:Bind Title}" /> </Button> </StackPanel> </DataTemplate>

Además, {x:Bind} no es compatible con {RelativeSource} , normalmente puede nombrar el elemento y usar su nombre en Path como alternativa. Para obtener más información, consulte la comparación de características {x: Bind} y {Binding} .

Pero esto no se puede usar en DataTemplate ya que se supone que todas las Path son propiedad de NewsItem . Y en su caso, creo que lo que quiere pasar es el NewsItem no el Button , por lo que puede usar CommandParameter="{x:Bind}" para pasar el NewsItem como el CommandParameter .

PD: hay un pequeño error en el diseñador de XAML, aún puede obtener una Object reference not set to an instance of an object. error. Puede agregar un espacio después de Bind como {x:Bind } como solución alternativa.

Si uso {x:Bind {RelativeSource Self}} en una plantilla de datos, aparece el siguiente error al compilar:

Referencia a objeto no establecida como instancia de un objeto.

La idea es pasar el objeto con plantilla a una propiedad como un parámetro de comando. Aquí hay un ejemplo de MainPage.xaml :

<Page x:Class="XBindTest5.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:XBindTest5" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Page.Resources> <ResourceDictionary> <local:OpenItemCommand x:Key="OpenCommand"/> </ResourceDictionary> </Page.Resources> <StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <ItemsControl ItemsSource="{x:Bind NewsItems, Mode=OneWay}"> <ItemsControl.ItemTemplate> <DataTemplate x:DataType="local:NewsItem"> <StackPanel> <Button Command="{x:Bind {StaticResource OpenCommand}}" CommandParameter="{x:Bind {RelativeSource Self}}"> <TextBlock Text="{x:Bind Title}"/> </Button> </StackPanel> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> </StackPanel> </Page>

Un modelo simple se define en el archivo de código behinde MainPage.xaml.cs :

using System; using System.Collections.ObjectModel; using System.Windows.Input; using Windows.UI.Xaml.Controls; namespace XBindTest5 { public class NewsItem { public string Title { get; set; } } /// <summary> /// command to open the item /// </summary> public class OpenItemCommand : ICommand { public event EventHandler CanExecuteChanged; public bool CanExecute(object parameter) { return true; } public void Execute(object parameter) { // ... example ... } } public sealed partial class MainPage : Page { public ObservableCollection<NewsItem> NewsItems { get; set; } = new ObservableCollection<NewsItem>(new[] { new NewsItem() { Title = "Item 1" }, new NewsItem() { Title = "Item 2" } }); public MainPage() { this.InitializeComponent(); } } }


Déjame responder más específicamente a esto. Solo hay un contexto de datos posible para x: bind y esa es la clase subyacente. En una página, es la página (o el código subyacente). En una plantilla de datos, es la clase de respaldo especificada en la propiedad tipo de destino de la plantilla de datos. Como un aparte, en una plantilla de control, x: bind no es compatible en absoluto, aunque solo es cuestión de tiempo.

Todo lo que quiere decir es que el contexto de datos de x: bind es fijo, y dependiendo de dónde se use, puedo decirle el contexto de los datos sin mirar a su XAML. ¿Por qué tan rígido? En parte, simplifica la generación de códigos a su alrededor. Además, para simplificar la implementación también. En cualquier caso, esta es una regla fija, y RelativeSource, ElementName, y Source y no soportados en x: bind.

Esto no significa que no pueda hacer referencia al self de la familia de referencia, solo tiene que hacerlo con un x: name especificado. Haría algo como esto <Tag x:Name="Jerry" Tag="Nixon" Text="{x:Bind Jerry.Tag}" /> .

¿Por qué falla esa muestra en particular? A diferencia de {binding} , {x:bind} requiere tipos coincidentes, lo que significa que la cadena de texto se puede lanzar y establecer en el objeto Tag, pero el objeto Tag no se puede subir y establecer en el valor de cadena de texto. El take-away para ti está usando x: bind significa que tus tipos deben coincidir.

Espero que esto te ayude a avanzar.

La mejor de las suertes.