[英]chaining dependency properties xaml wpf
我有一個用戶控件,希望通過其父xaml(在本例中為wpf頁面)進行訪問。 我的用戶控件具有label屬性,我希望通過將其綁定到傳遞到頁面xaml的datacontext中來設置頁面xaml。
在下面的示例中,當前來自xaml頁面的數據綁定似乎正常工作。 我可以通過頁面xaml設置用戶控件標簽的內容,只要我不嘗試將其綁定到頁面數據上下文,當我嘗試這樣做時,標簽始終顯示為空白。
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>
后面的用戶控制代碼
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);
}
}
頁面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字段的標簽似乎正在運行,並且設置attr字段似乎正在正常運行/也如預期。 因此,只有Val字段無法工作。
已更新,以包括后面的頁面代碼。 盡管這里幾乎沒有任何事情發生。
public partial class SceneView : Page
{
public Scene scene { get; set; }
public SceneView(Scene s)
{
InitializeComponent();
scene = s;
this.DataContext = scene;
}
}
我了解DP中的即時消息非常新穎,因此極有可能以完全不同的方式更好地完成即時消息。 在這種情況下,場景對象具有Im使用頁面和用戶控件公開的多個字段。 我已經用代碼編寫了整個應用程序,而沒有任何xaml,但是現在我正試圖自學xaml,並使下一個版本的原型更加流暢,並將所需的編碼減少80%。
我嘗試將場景對象(即頁面對象的數據上下文)發送給用戶控件。 page.DataContext.episode.Key是后面代碼中的合法字段。 通過上面的xaml,我正在尋找要發送到Val字段的值,該字段隨后將更新ValText(usercontrol中的標簽)Content屬性。
我已經弄清楚了這個問題。大多數是因為我在xaml仍然是個新手。
我意識到,如果未使用get / set訪問器聲明字段,則datacontext不會訪問字段。 我在后面的頁面代碼中更改了場景聲明,以使其成為一個依賴對象,而不是使用綁定屬性更改事件來設置用戶控件標簽內容,而不是鏈接綁定。
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>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.