2011-10-04 84 views
0

部落,帆布子不移位

我已經構建了一個Silverlight自定義控件TextBubble,它是網格中的橢圓和文本塊。我將通過代碼按需將這些文本氣泡添加到畫布對象。當我這樣做時,TextBubble的屬性被設置,但是當對象出現在畫布上時不會反映出來。

如果我手動構建相同的結構並將其添加到canvas,canvas.Children.Add(grid),則此子顯示正確。

使用TextBubble,顯示文本和橢圓,但直徑和X,Y沒有被應用,氣泡出現在畫布的左上角。

感謝您的幫助, -AM

代碼工作的:一點不

Grid g = new Grid(); 
g.SetValue(Canvas.TopProperty, 100.0); 
g.SetValue(Canvas.LeftProperty, 100.0); 
Ellipse e = new Ellipse(); 
e.Width = 50; 
e.Height = 50; 
e.Fill = new SolidColorBrush(Colors.Green); 
g.Children.Add(e); 
TextBlock t = new TextBlock(); 
t.Text = "TEST"; 
t.HorizontalAlignment = System.Windows.HorizontalAlignment.Center; 
t.VerticalAlignment = System.Windows.VerticalAlignment.Center; 
g.Children.Add(t); 
this.canvas.Children.Add(g); 

代碼:

TextBubble bubble = new TextBubble(); 
bubble.Text = "TEST"; 
bubble.Diameter = 50; 
bubble.Fill = new SolidColorBrush(Colors.Green); 
bubble.X = 100; 
bubble.Y = 100; 
canvas.Children.Add(bubble); 

TextBubble對象:

public class TextBubble : Control { 

public TextBubble() { 
    this.DefaultStyleKey = typeof(TextBubble); 
} 

public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
     "Text", 
     typeof(string), 
     typeof(TextBubble), 
     new PropertyMetadata(new PropertyChangedCallback(OnTextChanged))); 

public static readonly DependencyProperty DiameterProperty = DependencyProperty.Register(
     "Diameter", 
     typeof(int), 
     typeof(TextBubble), 
     new PropertyMetadata(new PropertyChangedCallback(OnDiameterChanged))); 

public static readonly DependencyProperty FillProperty = DependencyProperty.Register(
     "Fill", 
     typeof(Brush), 
     typeof(TextBubble), 
     new PropertyMetadata(new PropertyChangedCallback(OnFillChanged))); 

public static readonly DependencyProperty XCoordProperty = DependencyProperty.Register(
     "X", 
     typeof(double), 
     typeof(TextBubble), 
     new PropertyMetadata(new PropertyChangedCallback(OnXCoordChanged))); 

public static readonly DependencyProperty YCoordProperty = DependencyProperty.Register(
     "Y", 
     typeof(double), 
     typeof(TextBubble), 
     new PropertyMetadata(new PropertyChangedCallback(OnYCoordChanged))); 


public string Text { 
    get { return (string)this.GetValue(TextProperty); } 
    set { base.SetValue(TextProperty, value); } 
} 

public int Diameter { 
    get { return (int)this.GetValue(DiameterProperty); } 
    set { base.SetValue(DiameterProperty, value); } 
} 

public Brush Fill { 
    get { return (Brush)this.GetValue(FillProperty); } 
    set { base.SetValue(FillProperty, value); } 
} 

public double X { 
    get { return (double)this.GetValue(XCoordProperty); } 
    set { base.SetValue(XCoordProperty, value); } 
} 

public double Y { 
    get { return (double)this.GetValue(YCoordProperty); } 
    set { base.SetValue(YCoordProperty, value); } 
} 
} 

Generic.xml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
xmlns:local="clr-namespace:X4S.Controls" > 
<Style TargetType="local:TextBubble"> 
    <Setter Property="Text" Value="ABC" /> 
    <Setter Property="Diameter" Value="50" /> 
    <Setter Property="X" Value="100.0" /> 
    <Setter Property="Y" Value="100.0" /> 
    <Setter Property="Fill" Value="GhostWhite" /> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="local:TextBubble"> 
       <Grid x:Name="LayoutRoot" Canvas.Top="{TemplateBinding Y}" Canvas.Left="{TemplateBinding X}" > 
        <Ellipse Fill="{TemplateBinding Fill}" Width="{TemplateBinding Diameter}" Height="{TemplateBinding Diameter}"/> 
        <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="{TemplateBinding Text}"/> 
       </Grid> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 
</ResourceDictionary> 

Got it!

向畫布子樹添加新的自定義控件時,我們得到了這個額外的東西(TextBubble),它們圍繞着網格 - 文本塊 - 橢圓束。那麼,TextBubble對象從來沒有設置它的位置或大小。因此,即使Text和Fill被應用於內部控件,這些屬性也不受TextBubble的位置或大小的影響。

一旦我們將相同的位置和大小屬性應用到TextBubble本身 - 它真的奏效了。

的關鍵是這樣的:。 ((控制)canvas.GetDescendant())GetDescendant()的GetValue(Canvas.LeftProperty) 200.0

這表明網格確實有它的位置設置 - 但它的父母TextBubble沒有。

的修復:

private static void OnDiameterChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { 
    TextBubble textBubble = d as TextBubble; 
    textBubble.Width = (int)e.NewValue; 
    textBubble.Height = (int)e.NewValue; 
} 

private static void OnLeftChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { 
    TextBubble textBubble = d as TextBubble; 
    textBubble.SetValue(Canvas.LeftProperty, e.NewValue); 
} 

private static void OnTopChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { 
    TextBubble textBubble = d as TextBubble; 
    textBubble.SetValue(Canvas.TopProperty, e.NewValue); 
} 

有可能是一個更好的方法(我會研究它),但是這個工作。

+0

你試過在你的自定義控件的構造函數中:this.DataContext = this; – 2011-10-05 00:04:13

+0

我沒有嘗試this.DataContext = this;雖然沒有幫助。 –

+0

這裏不需要代碼,你的控件的模板可以很好地處理它 - 見我的答案。 – 2011-10-05 10:44:34

回答

0

下面是工作解決方案,我剛剛檢查過它。不過,你有兩個選擇: 1.設置的DataContext在構造和使用常規綁定 2.不要設置的DataContext並使用的RelativeSource作爲源(請參見下面的XAML)

這不完全明顯的畫布。左& Canvas.Top應該設置爲canvas的直接子節點,它是本地的:TextBubble。

<Style TargetType="local:TextBubble"> 
     <Setter Property="Text" Value="ABC" /> 
     <Setter Property="Diameter" Value="50" /> 


     <Setter Property="Canvas.Top" 
       Value="{Binding Path=Y, RelativeSource={RelativeSource Self}}" /> 
     <Setter Property="Canvas.Left" 
       Value="{Binding Path=X, RelativeSource={RelativeSource Self}}" /> 

     <Setter Property="Fill" Value="GhostWhite" /> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="local:TextBubble"> 
        <Grid x:Name="LayoutRoot" > 
         <Ellipse Fill="{TemplateBinding Fill}" Width="{TemplateBinding Diameter}" Height="{TemplateBinding Diameter}"/> 
         <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="{TemplateBinding Text}"/> 
        </Grid> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 
+0

顯然,FindAncestor和AncestorType在Silverlight 4.0中不可用。謝謝你的嘗試。我會繼續放棄這種方法,因爲笨重的方法可行,但很醜。 –

+0

奇怪的是,文本和填充屬性工作並應用於文本塊和橢圓。但直徑和X,Y值不是。是否有某種「更新你的懶狗」命令讓畫布更新? –