2009-07-26 22 views
1

如何將派生的<UserControl>的元素綁定到基礎元素<UserControl>XAML - 如何將派生的<UserControl>的元素綁定到基底的元素<UserControl>?

我已經定義了一個名爲Tile作爲我的基類的UserControl。這將是一個抽象基類,如果XAML在嘗試實例化從它派生的對象時不會出現障礙...

無論如何,迄今爲止Tile只包含一個依賴項屬性:OuterShape。它是一個System.Windows.Shapes.Shape對象(也是抽象的)。因此:所有的瓷磚都會有一些與它們相關的視覺形狀,用於渲染。但有許多不同類型的瓷磚---一些與System.Windows.Shapes.Paths,一些與System.Windows.Shapes.Polygons等

所以現在我正在處理第一個派生的UserControl:PolyTile。顧名思義,這是一個使用System.Windows.Shapes.Polygon作爲其「OuterShape」屬性的Tile。

我遇到的問題是,我無法弄清楚如何將XAML <Polygon>元素成功綁定到基類的Shape屬性。

/************ 
** Tile.cs ** 
************/ 
// This class contains a generic shape, and that's all. 
// This class does NOT have a XAML file to go with it. It is purely code implemented. 
public class Tile : System.Windows.Controls.UserControl 
{ 
    public static readonly System.Windows.DependencyProperty OuterShapeProperty 
     = System.Windows.DependencyProperty.Register( "OuterShape", 
                 typeof(System.Windows.Shapes.Shape), 
                 typeof(Tile)); 
    public System.Windows.Shapes.Shape OuterShape 
    { get { return (System.Windows.Shapes.Shape)GetValue(OuterShapeProperty); } 
     set { SetValue(OuterShapeProperty, (System.Windows.Shapes.Shape)value); } 
    } 
} 

........................

<!--***************** 
*** PolyTile.xaml *** 
******************--> 
<local:Tile x:Name="__PolyTile__" x:Class="WPFApplication1.PolyTile" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:WPFApplication1"> 
    <Grid Name="grdMain"> 
     <Polygon Name="OuterPoly" /> 
      <!--OuterPoly needs to be data-bound (OneWay) 
      to the OuterShape property of the Tile UserControl. 
      That way, when my derived class sets OuterShape to a new <Polygon> element, 
      OuterShape will show up on the screen as a <Polygon>--> 
    </Grid> 
</local:Tile> 

......... ...............

/**************** 
** PolyTile.cs ** 
****************/ 
// This class encapsulates a tile that is in the shape of a specified <Polygon> element. 
/// <summary> 
/// Interaction logic for PolyTile.xaml 
/// </summary> 
public partial class PolyTile : Tile // Derived from Tile 
{ 
    public PolyTile() 
    { 
     InitializeComponent(); 

     System.Windows.Data.BindingExpressionBase BindExp; 
     PolyConverter polyConverter = new PolyConverter(); 

     System.Windows.Data.Binding PolyBinding = new System.Windows.Data.Binding("OuterPoly"); 
     PolyBinding.Source = __PolyTile__; 
     PolyBinding.Mode = System.Windows.Data.BindingMode.OneWayToSource; 
     PolyBinding.Converter = polyConverter; 
     BindExp = __PolyTile__.SetBinding(Tile.OuterShapeProperty, PolyBinding); 
    } 



    // The framework won't convert a base object into a derived object without an explicit cast ... 
    // ... in this case, that means I have to make a custom DataConverter. 
    [System.Windows.Data.ValueConversion(typeof(System.Windows.Shapes.Polygon), typeof(System.Windows.Shapes.Shape))] 
    protected class PolyConverter : System.Windows.Data.IValueConverter 
    { 
     public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture) 
     { return value; } 
     // OneWayToSource binding: Thus the Convert method is never used. 
     // Rather, ConverBack is used to cast the base <Shape> into a derived <Polygon> 

     public object ConvertBack(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture) 
     { 
      if (value.GetType() == typeof(System.Windows.Shapes.Polygon)) 
       return value; 
      else 
       return System.Windows.DependencyProperty.UnsetValue; 
     } 
    } 
} 

我看不出有任何可能的方式來設置這個在XAML約束力。 (雖然我不太瞭解DataContexts,並說我已經想到了一切......)

因此,我嘗試在後臺代碼中手動設置綁定。我嘗試了很多不同的方式來組織綁定路徑和源和目標元素。每當我得到一個致命的異常或一個PathError或一個UpdateSourceError類似的東西。

有誰知道我在做什麼錯?
任何意見非常感謝!

回答

0

這是可以做到使用XAML對象的語法

需要注意的是默認的數據背景下完美的作品是非常重要的,如果你試圖得到非常明確的會出現例如問題:。綁定如果添加ElementName="__PolyTile__"到會失敗捆綁。

在這個解決方案中似乎並不需要數據轉換器。這使得代碼更容易遵循,但也許是以一種類型安全爲代價的。

<!--***************** 
*** PolyTile.xaml *** 
******************--> 
<local:Tile x:Name="__PolyTile__" x:Class="WPFApplication1.PolyTile" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:WPFApplication1"> 

    <local:Tile.OuterShape> 
     <Binding Path="OuterPoly" Mode="OneWayToSource" /> 
    </local:Tile.OuterShape> 

    <Grid Name="grdMain"> 
     <Polygon Name="OuterPoly" /> 
    </Grid> 

</local:Tile> 
2

你可以做到這幾個方面

,你可以使用相對來源: -

<TextBlock 
    Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:ParentUserControl}}, Path=MyProperty}" /> 

,或者您可以使用元素名綁定,我認爲更容易閱讀。 (您必須使用x:用戶控件名稱語法來命名XAML文件中的整個控制

<TextBlock 
    Text="{Binding ElementName=childUserControl, Path=MyProperty}" /> 

here是一個小的測試項目中,我寫測試這個

+0

這幾乎回答了我的問題。你能重寫一下這段代碼嗎,這樣你就可以將子文本框控件綁定到父文本框的屬性了?我試圖綁定控件本身 - 不僅僅是控件的一個屬性,比如「Text」 – Giffyguy 2009-07-27 21:31:20