Che cosa stai provando a fare questo richiede di associare i dati alla proprietà ActualWidth
? Questo è un problema noto con Silverlight e non esiste una soluzione semplice.
Una cosa che si potrebbe fare è impostare l'albero visivo in modo tale che non sia necessario impostare effettivamente la larghezza del rettangolo e lasciare che si allunghi alle dimensioni appropriate. Quindi nell'esempio sopra, se rimuovi la tela (o cambia la tela su un altro pannello) e lasci lo Rectangle
di HorizontalAlignment
impostato su Stretch
, occuperà tutta la larghezza disponibile (effettivamente la larghezza della griglia).
Tuttavia, questo potrebbe non essere possibile nel tuo caso particolare e potrebbe essere davvero necessario impostare il databinding. È già stato stabilito che ciò non è possibile direttamente, ma con l'aiuto di un oggetto proxy, possiamo impostare l'associazione richiesta. Considerate questo codice:
public class ActualSizePropertyProxy : FrameworkElement, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public FrameworkElement Element
{
get { return (FrameworkElement)GetValue(ElementProperty); }
set { SetValue(ElementProperty, value); }
}
public double ActualHeightValue
{
get{ return Element == null? 0: Element.ActualHeight; }
}
public double ActualWidthValue
{
get { return Element == null ? 0 : Element.ActualWidth; }
}
public static readonly DependencyProperty ElementProperty =
DependencyProperty.Register("Element", typeof(FrameworkElement), typeof(ActualSizePropertyProxy),
new PropertyMetadata(null,OnElementPropertyChanged));
private static void OnElementPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((ActualSizePropertyProxy)d).OnElementChanged(e);
}
private void OnElementChanged(DependencyPropertyChangedEventArgs e)
{
FrameworkElement oldElement = (FrameworkElement)e.OldValue;
FrameworkElement newElement = (FrameworkElement)e.NewValue;
newElement.SizeChanged += new SizeChangedEventHandler(Element_SizeChanged);
if (oldElement != null)
{
oldElement.SizeChanged -= new SizeChangedEventHandler(Element_SizeChanged);
}
NotifyPropChange();
}
private void Element_SizeChanged(object sender, SizeChangedEventArgs e)
{
NotifyPropChange();
}
private void NotifyPropChange()
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("ActualWidthValue"));
PropertyChanged(this, new PropertyChangedEventArgs("ActualHeightValue"));
}
}
}
possiamo usare questo in XAML come segue:
<Grid x:Name="LayoutRoot">
<Grid.Resources>
<c:ActualSizePropertyProxy Element="{Binding ElementName=LayoutRoot}" x:Name="proxy" />
</Grid.Resources>
<TextBlock x:Name="tb1" Text="{Binding ActualWidthValue, ElementName=proxy}" />
</Grid>
Così abbiamo sono vincolanti TextBlock.Text alla ActualWidthValue sull'oggetto proxy. L'oggetto proxy a sua volta fornisce ActualWidth of the Element, che è fornito da un altro Binding.
Questa non è una soluzione semplice al problema, ma è la soluzione migliore che posso immaginare per come collegarsi a ActualWidth.
Se hai spiegato un po 'di più il tuo scenario, potrebbe essere possibile trovare una soluzione più semplice. DataBinding potrebbe non essere richiesto affatto; sarebbe possibile semplicemente impostare la proprietà dal codice in un gestore di eventi SizeChanged?
Ho seguito l'approccio suggerito con il gestore di eventi SizeChanged e sto ottenendo l'effetto desiderato.Per spiegare lo scenario un po 'di più avevo bisogno di legarsi alla proprietà ActualWidth come se avessi un po' di una strana progettazione dell'interfaccia utente che richiede che alcuni elementi appaiano fuori dai limiti del controllo. –
Più di 5 anni e funziona ancora con WinRT ;-) - con una piccola modifica: il nuovo SizeEventHandler (Element_SizeChanged) deve essere sostituito direttamente da Element_SizeChanged. – TheEye