2014-08-30 4 views
0

У меня есть usercontrol, который я хочу получить через его родительский xaml (в данном случае страницу wpf). мой пользовательский элемент управления имеет свойство метки, которое я хочу установить через страницу xaml, привязывая ее к datacontext, который передается на страницу xaml.свойства зависимостей привязки xaml wpf

В настоящий момент в приведенном ниже примере привязка данных со страницы xaml работает правильно. Я могу установить содержание пользовательских ярлыков элементов управления через страницу xaml, пока я не пытаюсь привязать его к страницам datacontext, когда я это делаю, ярлык всегда выглядит пустым.

Ive следовал за рядом других смежных примеров, предложенных на этом сайте, но пока еще не определил, где я ошибаюсь. Любые советы будут очень признательны.

UserControl XAML

<UserControl x:Class="Pipeline_General.Custom_Controls.AttributeStack" 
     xmlns:pm="clr-namespace:Pipeline_General" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     mc:Ignorable="d" 
     DataContext = "{Binding RelativeSource={RelativeSource Self}}" 
     d:DesignHeight="30" d:DesignWidth="300"> 
<Grid> 
    <Grid.ColumnDefinitions> 
     <ColumnDefinition Width="2*" /> 
     <ColumnDefinition Width="3*" /> 
    </Grid.ColumnDefinitions> 
    <Label Foreground="{x:Static pm:myBrushes.pink}" Content="{Binding Path=Attr}" Grid.Column="0" HorizontalAlignment="Right" FontFamily="Calibri" FontSize="14" Margin="5,0,5,0"/> 
    <Label x:Name="ValLabel" Foreground="{x:Static pm:myBrushes.blue}" Grid.Column="1" HorizontalAlignment="Left" FontFamily="Calibri" FontSize="14" Margin="5,0,5,0"/> 
</Grid> 

UserControl Код За

public partial class AttributeStack : UserControl 
{ 


    public static readonly DependencyProperty AttrProperty = DependencyProperty.Register 
     (
      "Attr", 
      typeof(string), 
      typeof(AttributeStack), 
      new PropertyMetadata(string.Empty) 
     ); 

    public static readonly DependencyProperty ValProperty = DependencyProperty.Register 
      (
       "Val", 
       typeof(string), 
       typeof(AttributeStack), 
       new PropertyMetadata(string.Empty) 
      ); 

    public static readonly DependencyProperty ValTextProperty = DependencyProperty.Register 
     (
       "ValText", 
       typeof(string), 
       typeof(AttributeStack), 
       new PropertyMetadata(string.Empty) 
     ); 

    public string Val 
    { 
     get { return (string)GetValue(ValProperty); } 
     set { SetValue(ValProperty, value); } 
    } 

    public string ValText 
    { 
     get { return (string)GetValue(ValTextProperty); } 
     set { SetValue(ValTextProperty, value); } 
    } 


    public string Attr 
    { 
     get { return (string)GetValue(AttrProperty); } 
     set { SetValue(AttrProperty, value); } 
    } 


    public AttributeStack() 
    { 
     InitializeComponent(); 

     Binding valBinding = new Binding("Val") 
     { 
      Source = Val, 
      Mode = BindingMode.OneWay 
     }; 

     Binding textBinding = new Binding("Content") 
     { 
      Source = this.ValLabel.Content, 
      Mode = BindingMode.OneWay 
     }; 

     ValLabel.SetBinding(Label.ContentProperty, valBinding); 
     this.SetBinding(AttributeStack.ValTextProperty, textBinding); 
    } 
} 

Page XAML

<Page x:Class="Pipeline_General.SceneView" x:Name="page" 
    xmlns:pm="clr-namespace:Pipeline_General" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    mc:Ignorable="d" 
    xmlns:cc="clr-namespace:Pipeline_General.Custom_Controls" 
    d:DesignHeight="800" d:DesignWidth="600" 
    DataContext = "{Binding RelativeSource={RelativeSource Self}}" 
    Title="SceneView"> 
<Grid> 
    <ScrollViewer> 
     <Grid> 
      <Grid.ColumnDefinitions> 
       <ColumnDefinition Width="*" /> 
       <ColumnDefinition Width="*" /> 
      </Grid.ColumnDefinitions> 
      <StackPanel Grid.Column="0"> 
       <Expander IsExpanded="True" Margin="5"> 
        <Expander.Header> 
         <Grid x:Name="Grid" HorizontalAlignment="Stretch" Width="NaN"> 
          <Border x:Name="Border" Background="Transparent" HorizontalAlignment="Stretch" BorderBrush="{x:Static pm:myBrushes.blue}" BorderThickness="0,0,0,1" 
         Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Expander}}, Path=ActualWidth}"> 
           <TextBlock x:Name="HeaderText" FontSize ="18" FontFamily="Calibri" Foreground="{x:Static pm:myBrushes.blue}" Text="General Info: " /> 
          </Border> 
         </Grid> 
        </Expander.Header> 
        <StackPanel> 
         <Separator Foreground="Transparent" Height="0" Margin="5"/> 
         <cc:AttributeStack Attr="Title:" Val="{Binding Path=DataContext.Title, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Page}}"/> 
         <Separator Foreground="Transparent" Height="0" Margin="5"/> 
         <cc:AttributeStack Attr="Episode:" Val="{Binding Path=DataContext.episode.Key, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Page}}"/> 
         <cc:AttributeStack Attr="Sequence:" Val="{Binding Path=DataContext.sequence.Key, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Page}}"/> 
         <cc:AttributeStack Attr="Scene:" Val="{Binding Path=Title, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Page}}"/> 
         <Separator Foreground="Transparent" Height="0" Margin="5"/> 
         <cc:AttributeStack Attr="Assigned:" Val="{Binding Path=Title, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Page}}"/> 
         <cc:AttributeStack Attr="Status:" Val="{Binding Path=Title, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Page}}"/> 
         <Separator Foreground="Transparent" Height="0" Margin="5"/> 
         <cc:AttributeStack Attr="Last Saved (Time):" Val="{Binding Path=Title, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Page}}"/> 
         <cc:AttributeStack Attr="Last Saved (User):" Val="{Binding Path=Title, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Page}}"/> 
         <Separator Foreground="Transparent" Height="0" Margin="5"/> 
         <cc:AttributeStack Attr="Due:" Val="{Binding Path=Title, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Page}}"/> 
        </StackPanel> 
       </Expander> 
      </StackPanel> 

      <StackPanel Grid.Column="1"> 
       <cc:Playblast_Viewer x:Name="PlayblastView"/> 
       <cc:FeedbackCtrl Header="Feedback:"/> 
       <cc:FeedbackCtrl Header="NoticeBoard:"/> 
      </StackPanel> 

     </Grid> 
    </ScrollViewer> 
</Grid> 

Метка связывания с DataContext.Title поле, кажется, работает, и настройки полей атр, кажется, работает правильно /, как ожидается, также. Поэтому это только поля Val, которые я не могу получить.

Обновлено, чтобы включить код страницы позади. здесь почти ничего не происходит.

public partial class SceneView : Page 
{ 
    public Scene scene { get; set; } 
    public SceneView(Scene s) 
    { 
     InitializeComponent(); 
     scene = s; 
     this.DataContext = scene; 
    } 
} 

Я понимаю, что им вполне NEWB в DP так существует высокая вероятность того, что им пытаются сделать можно было бы сделать лучше, совершенно по-другому. В этом случае объект сцены имеет множество полей, которые Im использует страницу и пользовательские элементы управления для раскрытия. Ive написал все приложение в коде без каких-либо xaml, но теперь я пытаюсь научить себя xaml, и следующая версия прототипа будет намного более бегло и уменьшит требуемую кодировку на 80%.

Объект сцены, являющийся контекстом данных объекта страницы, я пытаюсь отправить поля из пользовательских элементов управления, т.е. page.DataContext.episode.Key - это законное поле в коде. И через вышеприведенный xaml я ищу его значение для отправки в поле Val, которое затем обновит свойство ContentText (метка в usercontrol) Content.

+0

цепочки/проводки никогда не проблема с свойства зависимостей. для меня ваша логика, похоже, запутана. Мне трудно понять желаемое. оценил, если бы вы могли что-то сделать для того же. то есть. источник собственности, посредники и цель. – pushpraj

+0

Можете ли вы поделиться кодом для страницы, а? –

+0

См. Здесь http://stackoverflow.com/questions/23482734/wpf-chain-binding?rq=1 – Developer

ответ

0

Ive выяснил проблему/проблемы. Большинство из них, потому что им все еще новичок в xaml.

Я понял, что datacontext не имеет доступа к полям, если они не объявлены с помощью get/set accessors. Я изменил объявление сцены в коде страницы позади, так что это был объект зависимостей. Вместо привязки привязок я использовал событие с изменением свойства зависимостей, чтобы установить содержимое метки ярлыков usercontrols.

public partial class AttributeStack : UserControl 
{ 
    #region Val (DependencyProperty) 
    public string Val 
    { 
     get { return (string)GetValue(ValProperty); } 
     set { SetValue(ValProperty, value); } 
    } 
    public static readonly DependencyProperty ValProperty = 
     DependencyProperty.Register("Val", typeof(string), typeof(AttributeStack), 
      new PropertyMetadata { PropertyChangedCallback = ValChanged }); 
    private static void ValChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     AttributeStack aStack = d as AttributeStack; 
     if (aStack != null && e.NewValue != null) 
     { 
      aStack.ValLabel.Content = e.NewValue.ToString(); 
     } 
    } 
    #endregion 

    public static readonly DependencyProperty AttrProperty = DependencyProperty.Register 
     (
      "Attr", 
      typeof(string), 
      typeof(AttributeStack), 
      new PropertyMetadata(string.Empty) 
     ); 

    public string Attr 
    { 
     get { return (string)GetValue(AttrProperty); } 
     set { SetValue(AttrProperty, value); } 
    } 

    public AttributeStack() 
    { 
     InitializeComponent(); 
    } 
} 

}

public partial class SceneView : Page 
{ 
    public static readonly DependencyProperty sceneProperty = DependencyProperty.Register 
     (
      "scene", 
      typeof(Scene), 
      typeof(SceneView) 
     ); 

    public Scene scene 
    { 
     get { return (Scene)GetValue(sceneProperty); } 
     set { SetValue(sceneProperty, value); } 
    } 
    public SceneView(Scene s) 
    { 
     InitializeComponent(); 
     scene = s; 

     this.DataContext = scene; 
    } 
} 

<Page x:Class="Pipeline_General.SceneView" x:Name="page" 
    xmlns:pm="clr-namespace:Pipeline_General" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    mc:Ignorable="d" 
    xmlns:cc="clr-namespace:Pipeline_General.Custom_Controls" 
    d:DesignHeight="800" d:DesignWidth="600" 
    DataContext = "{Binding RelativeSource={RelativeSource Self}}" 
    Title="SceneView"> 
<Grid> 
    <ScrollViewer> 
     <Grid> 
      <Grid.ColumnDefinitions> 
       <ColumnDefinition Width="*" /> 
       <ColumnDefinition Width="*" /> 
      </Grid.ColumnDefinitions> 
      <StackPanel Grid.Column="0"> 
       <Expander IsExpanded="True" Margin="5"> 
        <Expander.Header> 
         <Grid x:Name="Grid" HorizontalAlignment="Stretch" Width="NaN"> 
          <Border x:Name="Border" Background="Transparent" HorizontalAlignment="Stretch" BorderBrush="{x:Static pm:myBrushes.blue}" BorderThickness="0,0,0,1" 
         Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Expander}}, Path=ActualWidth}"> 
           <TextBlock x:Name="HeaderText" FontSize ="18" FontFamily="Calibri" Foreground="{x:Static pm:myBrushes.blue}" Text="General Info: " /> 
          </Border> 
         </Grid> 
        </Expander.Header> 
        <StackPanel> 
         <Separator Foreground="Transparent" Height="0" Margin="5"/> 
         <cc:AttributeStack Attr="Title:" Val="{Binding Path=scene.Title, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Page}}"/> 
         <Separator Foreground="Transparent" Height="0" Margin="5"/> 
         <cc:AttributeStack Attr="Episode:" Val="{Binding Path=scene.episode.Key, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Page}}"/> 
         <cc:AttributeStack Attr="Sequence:" Val="{Binding Path=scene.sequence.Key, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Page}}"/> 
         <cc:AttributeStack Attr="Scene:" Val="{Binding Path=scene.Key, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Page}}"/> 
         <Separator Foreground="Transparent" Height="0" Margin="5"/> 
         <cc:AttributeStack Attr="Assigned:" Val="{}"/> 

         <cc:AttributeStack Attr="Status:" Val="{Binding Path=Title, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Page}}"/> 
         <Separator Foreground="Transparent" Height="0" Margin="5"/> 
         <cc:AttributeStack Attr="Last Saved (Time):" Val="{Binding Path=Title, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Page}}"/> 
         <cc:AttributeStack Attr="Last Saved (User):" Val="{Binding Path=Title, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Page}}"/> 
         <Separator Foreground="Transparent" Height="0" Margin="5"/> 
         <cc:AttributeStack Attr="Due:" Val="{Binding Path=Title, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Page}}"/> 
        </StackPanel> 
       </Expander> 
      </StackPanel> 

      <StackPanel Grid.Column="1"> 
       <cc:Playblast_Viewer x:Name="PlayblastView"/> 
       <cc:FeedbackCtrl Header="Feedback"/> 
       <cc:FeedbackCtrl Header="NoticeBoard"/> 
      </StackPanel> 

     </Grid> 
    </ScrollViewer> 
</Grid> 

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