2009-03-20 6 views
2

У меня есть небольшая проблема привязки данных. (Я обычно ...)WPF: привязка данных - пользовательский контроль не ведет

Это ошибка я получаю в окне вывода во время выполнения:

System.Windows.Data Error: 39 : BindingExpression path error: 'CurrentKlokke' property not found on 'object' ''UIKlokke' (Name='anaKlokke')'. BindingExpression:Path=CurrentKlokke; DataItem='UIKlokke' (Name='anaKlokke'); target element is 'UIKlokke' (Name='anaKlokke'); target property is 'klokke' (type 'Klokke') 

«anaKlokke» является экземпляром «UIKlokke», в UserControl, представляющих аналоговые часы.

<UserControl 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:local="clr-namespace:Klokketrening" 
     mc:Ignorable="d" 
     x:Class="Klokketrening.UIKlokke" 
     x:Name="UserControl" 
     DataContext="{Binding RelativeSource={RelativeSource self}}" 
     d:DesignWidth="400" d:DesignHeight="400"> 

     <UserControl.Resources> 
      <ControlTemplate x:Key="clockTemplate"> 
       <Grid> 
        <Grid.Resources> 
         <local:TimeTilVinkel x:Key="hourToAngle"/> 
         <local:MinuttTilVinkel x:Key="minuteToAngle"/> 
        </Grid.Resources> 
        <Grid.LayoutTransform> 
         <ScaleTransform ScaleX="2" ScaleY="2" /> 
        </Grid.LayoutTransform> 
        <Ellipse Width="108" Height="108" StrokeThickness="3"> 
         <Ellipse.Stroke> 
          <LinearGradientBrush> 
           <GradientStop Color="LightBlue" Offset="0" /> 
           <GradientStop Color="DarkBlue" Offset="1" /> 
          </LinearGradientBrush> 
         </Ellipse.Stroke> 
        </Ellipse> 


        <Canvas Width="102" Height="102"> 
         <Ellipse Width="8" Height="8" Fill="Black" Canvas.Top="46" Canvas.Left="46" /> 
         <Rectangle x:Name="HourHand" Canvas.Top="26" Canvas.Left="48" Fill="Black" Width="4" Height="25"> 
          <Rectangle.RenderTransform> 
           <RotateTransform x:Name="HourHand2" CenterX="2" CenterY="25" Angle="{Binding Converter={StaticResource hourToAngle}}" />      
          </Rectangle.RenderTransform> 
         </Rectangle> 
         <Rectangle x:Name="MinuteHand" Canvas.Top="16" Canvas.Left="49" Fill="Black" Width="2" Height="35"> 
          <Rectangle.RenderTransform> 
           <RotateTransform CenterX="1" CenterY="35" Angle="{Binding Converter={StaticResource minuteToAngle}}" /> 
          </Rectangle.RenderTransform> 
         </Rectangle> 
        </Canvas> 
       </Grid> 
      </ControlTemplate> 
     </UserControl.Resources> 
     <Grid> 
      <Control Template="{StaticResource clockTemplate}" DataContext="{Binding klokke}" /> 
     </Grid> 
    </UserControl> 

и код позади:

public partial class UIKlokke 
{ 

    public Klokke klokke 
    { 
     get {return (Klokke)GetValue(UIKlokke.KlokkeProperty); } 
     set { SetValue(UIKlokke.KlokkeProperty, value); } 
    } 

    public static readonly DependencyProperty KlokkeProperty; 

    public UIKlokke() 
    { 
     this.InitializeComponent(); 
    } 

    static UIKlokke() 
    { 
     UIKlokke.KlokkeProperty = DependencyProperty.Register("klokke", typeof(Klokke), typeof(UIKlokke)); 
    } 
} 

Где я использую этот UserControl, я хочу, чтобы связать «klokke'-свойство в 'The UserControls' свойство с 'CurrentKlokke объекта Game'.

<local:UIKlokke x:Name="anaKlokke" Grid.Column="0" Grid.Row="1" klokke="{Binding CurrentKlokke}"/> 

CurrentKlokke - зависимое свойство.

public Klokke CurrentKlokke 
    { 
     get { return (Klokke)GetValue(Game.CurrentKlokkeProperty); } 
     set { SetValue(Game.CurrentKlokkeProperty, value); } 
    } 
    public static readonly DependencyProperty CurrentKlokkeProperty; 

    static Game() 
    { 
     Game.CurrentKlokkeProperty = DependencyProperty.Register("CurrentKlokke", typeof(Klokke), typeof(Game)); 
    } 

Я поставил DataContext для сетки, содержащей экземпляр UIKlokke в коде:

 _game = new Game(Game.GameLevel.Easy, 10); 
     gridGameUI.DataContext = _game; 

Я связывание ItemSource из в ListBox другого свойство объекта игры, и она отлично работает.

Может ли кто-нибудь помочь мне с этим?

ответ

2

Попробуйте удалить свойство Klokke из элемента управления UIKlokke и связать DataContext объекта anaKlokke к в Klokke непосредственно.

Кроме того, вам не нужно иметь элемент управления внутри сетки внутри usercontrol. Вы можете просто использовать UserControls.Template:

<UserControl ... DataContext="No needed its set on the game"> 
    <UserControl.Template> 
    <ControlTemplate> 
     <Grid> 
     <!-- ... --> 
     </Grid> 
    </ControlTemplate> 
    </UserControl.Template> 
</UserControl> 

Таким образом DataContext устанавливается право Повсеместно непосредственно на UserControl

Если вам необходимо получить доступ к Klokke в коде-за вы можете использовать

var klokke = DataContext as Klokke; 
if (klokke == null) return; 

// use klokke 
+0

Это похоже на работу! Но я считаю это немного странным. С моей точки зрения, usercontrol требует, чтобы это свойство было «самосохраненным» или «полным». Может быть, разные вещи при разработке «реальных» контролей? – Vegar

+0

DataContext justs продолжает проходить через визуальное дерево и просто берет рулон родителя. – bendewey

+0

обновил мой ответ, я точно не знаю, что вы просите. – bendewey

0

Не уверен в этом, я только начинаю с WPF. Но не следует использовать Path в вашем связывании так:

<local:UIKlokke x:Name="anaKlokke" 
       Grid.Column="0" Grid.Row="1" 
       klokke="{Binding Path=CurrentKlokke}"/> 
+1

{Binding Path = source} и {Binding source} - это то же самое, насколько я знаю. (Но тогда я тоже начинаю ...) – Vegar

+0

@Vegar исправить то же самое. – bendewey

 Смежные вопросы

  • Нет связанных вопросов^_^