2015-09-15 12 views
5

Ho passato la meglio su una mezza giornata cercando di rendere il ItemTemplate di un ListView con un UserControl configurabile tramite mezzo di un DependencyProperty su detto UserControl . Mi sono imbattuto in strane incoerenze riguardo i due diversi metodi Binding disponibili sulla piattaforma UAP di Windows 10 (Binding e x:Bind).Binding vs x: Bind, utilizzando StaticResource come predefinito e le loro differenze di DataContext

Il numero UserControl è simile a questo e fa parte di un componente del calendario personalizzato.

<UserControl 
    x:Class="FlowDesigner.UserControls.CalendarDayView" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="using:FlowDesigner.UserControls" 
    xmlns:vw="using:FlowDesigner.ViewModels" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:uc="using:FlowDesigner.UserControls" 
    mc:Ignorable="d" 
    d:DesignHeight="300" 
    d:DesignWidth="400" 
    x:Name="DateControl"> 
    <UserControl.Resources> 
     <DataTemplate x:Key="DefaultDataTemplate" x:DataType="vw:Event" > 
      <uc:EventListTemplate IsToday="{Binding Date, Converter={StaticResource IsTodayConverter}}" 
           Date="{Binding Date, Mode=OneWay}" 
           Summary="{Binding Path=Summary, Mode=OneWay}" /> 
     </DataTemplate> 
    </UserControl.Resources> 
    <RelativePanel Background="White" BorderBrush="Black" BorderThickness="1" DataContext="{Binding ElementName=DateControl}"> 
     <TextBlock x:Name="DayText" TextAlignment="Center" VerticalAlignment="Center" /> 
     <TextBlock x:Name="MonthText" TextAlignment="Center" VerticalAlignment="Center" RelativePanel.RightOf="DayText" /> 
     <ListView x:Name="EventList" ItemsSource="{x:Bind Events, Mode=OneWay}" 
       ItemTemplate="{Binding Path=EventItemTemplate, Mode=OneWay, FallbackValue={StaticResource DefaultDataTemplate}, TargetNullValue={StaticResource DefaultDataTemplate}}" 
       RelativePanel.Below="DayText" RelativePanel.AlignLeftWithPanel="True" RelativePanel.AlignRightWithPanel="True"> 

     </ListView> 
    </RelativePanel> 
</UserControl> 

Il EventItemTemplate è un DependencyProperty del UserControl.

public DataTemplate EventItemTemplate 
{ 
    get { return (DataTemplate)GetValue(EventItemTemplateProperty); } 
    set { SetValue(EventItemTemplateProperty, value); } 
} 

public static readonly DependencyProperty EventItemTemplateProperty = 
     DependencyProperty.Register("EventItemTemplate", typeof(DataTemplate), typeof(CalendarDayView), new PropertyMetadata(null)); 

Che viene alterato su una delle pagine radice per lo stile della ListView in un modo o l'altro, in questo modo.

<Style TargetType="uc:CalendarDayView"> 
    <Setter Property="EventItemTemplate"> 
     <Setter.Value> 
      <DataTemplate x:DataType="vw:Event" > 
       <TextBlock Text="{Binding Summary, Mode=OneWay}" /> 
      </DataTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

Questa è in realtà una versione funzionante, ma ho dovuto armeggiare un po 'con esso. I primi tentativi sono stati effettuati da me con x:Bind e Binding e senza lo DataContext su RelativePanel poiché lo UserControl è ora. x:Bind sarebbe funzionale quando si imposta un valore su EventItemTemplate nella pagina principale, ma non sarebbe possibile utilizzare il valore predefinito DataTemplate specificato dallo StaticResource quando la pagina radice non ha specificato nulla. Binding d'altra parte userebbe il valore predefinito DataTemplate in qualsiasi momento, anche quando la pagina radice aveva un altro valore impostato su EventItemTemplate.

Impostando DataContext su RelativePanel su UserControlBinding ha iniziato a funzionare come desiderato anche esso. x:Bind mostra ancora lo stesso comportamento.

Adesso ho capito che non lo fa per Binding legano predefinito al s DataContextUserControl', ma non sono ancora del tutto sicuro perché x:Bind non funziona. Questo comportamento è previsto o c'è qualcosa di sbagliato in tutto il mio schema qui ed è quello che mi è venuto in mente solo un hack fortunato?

risposta

8

Da {x:Bind} markup extension:

La {x: Bind} markup extension-nuova per Windows 10-è un'alternativa a {} Binding. {x: Bind} non include alcune delle funzionalità di {Binding}, ma viene eseguito in meno tempo e in meno di memoria rispetto a {Binding} e supporta un debug migliore.

Al momento del caricamento XAML, {x: Bind} viene convertito in ciò che si può pensare come oggetto vincolante e questo oggetto ottiene un valore da una proprietà su un'origine dati. L'oggetto vincolante può essere configurato facoltativamente per osservare le modifiche nel valore della proprietà dell'origine dati e aggiornarsi in base a tali modifiche. Può anche essere configurato facoltativamente per trasferire le modifiche nel proprio valore alla proprietà sorgente. Gli oggetti di bind creati da {x: Bind} e {Binding} sono in gran parte equivalenti dal punto di vista funzionale. Ma {x: Bind} esegue il codice per scopi speciali, che genera in fase di compilazione, e {Binding} utilizza l'ispezione dell'oggetto runtime per scopi generici. Di conseguenza, le associazioni {x: Bind} (spesso indicate come associazioni compilate) offrono grandi prestazioni, forniscono la convalida in fase di compilazione delle espressioni di collegamento e supportano il debug, consentendo di impostare i punti di interruzione nei file di codice che vengono generati come classe per la tua pagina.Questi file possono essere trovati nella tua cartella obj, con nomi come (per C#) .g.cs.

Problemi correlati