Binding with ordinary property
I'm new to the forum and very new to silverlight. My colleague and I are working on a custom application. We are creating a menu system that will only display buttons if that user is in the assigned role. A new property has been created to allow us to define roles, and for testing purposes we are just trying to assign this value, which is a string, to the textblock property. Some code is attached.
This is one of the items to add to the collection. the allowedroles property passes a string, this can be seen through the debugger
<MenuButton:VerticalButtonCollection x:Key="VerticalButtonsDS" d:IsDataSource="True">
<MenuButton:VerticalButton AllowedRoles="test, test2">
<TextBlock Text="{Binding AllowedRoles}"></TextBlock>
</MenuButton:VerticalButton>
</MenuButton:VerticalButtonCollection>
Code for the allowed roles property
Public Shared ReadOnly AllowedRolesProperty As DependencyProperty = DependencyProperty.Register("AllowedRoles", GetType(String), GetType(mButton), New PropertyMetadata(New PropertyChangedCallback(AddressOf onAllowedRolesChanged)))
Public Shared Sub onAllowedRolesChanged(ByVal d As DependencyObject, ByVal args As DependencyPropertyChangedEventArgs)
Dim sender As mButton = CType(d, mButton)
sender.AllowedRoles = CStr(args.NewValue)
End Sub
The items are displayed in the list box, there are no errors, but the binding does not work. I even tried binding in a list data template. I apologize if this is confusing, I donβt know how to post something like this in easy-to-understand detail.
thank
source to share
When finished, follow these steps. One trick is that you cannot use a converter in a template binding to bind an object's DataContext to a template binding and then use regular binding to access it.
<UserControl.Resources>
<mt:AllowedRolesConverter x:Key="RolesConverter"></mt:AllowedRolesConverter>
<Style x:Key="VerticalButton1Style" TargetType="mt:VerticalButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="mt:VerticalButton">
<Grid x:Name="RootGrid" DataContext="{TemplateBinding AllowedRoles}" Visibility="{Binding Converter={StaticResource RolesConverter}}">
<Border x:Name="border" BorderThickness="1">
<Border.BorderBrush>
<SolidColorBrush x:Name="borderBrush" Opacity="0" Color="Blue"/>
</Border.BorderBrush>
<ContentPresenter x:Name="VBContent"
ContentTemplate="{TemplateBinding ContentTemplate}"
>
</ContentPresenter>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<mt:VerticalButtonCollection x:Key="TestCollection">
<mt:VerticalButton AllowedRoles="Test1"
Style="{StaticResource VerticalButton1Style}"
Click="VerticalButton_Click"
>
<TextBlock Text="Test Button"></TextBlock>
</mt:VerticalButton>
<mt:VerticalButton AllowedRoles="Test1"
Style="{StaticResource VerticalButton1Style}" Click="VerticalButton_Click_1">
<Ellipse Width="50" Height="50" Fill="Blue"></Ellipse>
</mt:VerticalButton>
</mt:VerticalButtonCollection>
<Style x:Key="ListItemStyle" TargetType="ListBoxItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<StackPanel x:Name="Root" Orientation="Horizontal">
<ContentPresenter Margin="5,5,5,5"/>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ListStyle" TargetType="ListBox">
<Setter Property="ItemContainerStyle" Value="{StaticResource ListItemStyle}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBox">
<Grid x:Name="Root">
<ItemsPresenter></ItemsPresenter>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White">
<ListBox Style="{StaticResource ListStyle}" ItemsSource="{StaticResource TestCollection}" />
</Grid>
Public Class VerticalButton
Inherits Button
Implements INotifyPropertyChanged
Public Property AllowedRoles() As String
Get
Return CStr(GetValue(AllowedRolesProperty))
End Get
Set(ByVal value As String)
SetValue(AllowedRolesProperty, value)
End Set
End Property
Public Shared ReadOnly AllowedRolesProperty As DependencyProperty = DependencyProperty.Register("AllowedRoles", GetType(String), GetType(VerticalButton), New PropertyMetadata(New PropertyChangedCallback(AddressOf OnAllowedRolesChanged)))
Public Shared Sub OnAllowedRolesChanged(ByVal d As DependencyObject, ByVal args As DependencyPropertyChangedEventArgs)
Dim sender As VerticalButton = CType(d, VerticalButton)
sender.AllowedRoles = CStr(args.NewValue)
End Sub
Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
End Class
Public Class VerticalButtonCollection
Inherits ObservableCollection(Of VerticalButton)
End Class
source to share
When you use the Binding syntax, you are binding to a DataContext object. So your binding:
<MenuButton:VerticalButton AllowedRoles="test, test2">
<TextBlock Text="{Binding AllowedRoles}"></TextBlock>
</MenuButton:VerticalButton>
Basically they say that I got the "AllowedRoles" property in my DataContext. Since the data context is probably null (didn't see it set) you don't get any value in your text block.
What you probably want to do is define a template for your MenuButton, and then in the template you can say:
<TextBlock Text="{TemplateBinding AllowedRoles}"></TextBlock>
which will be set when you apply the template to the element.
Here are some links I posted on another thread on understanding templates and generic.xaml:
- Control setup
- Customizable user controls
- Fine-tuning the default styles
- 3 good links to generic.xaml
Good luck!
source to share
<MenuButton:VerticalButton AllowedRoles="test, test2">
The above line indicates the value of the allowed number. I am creating a new instance of the button at this point.
Where I am trying to link the allowed roles to the textbox is probably completely wrong, but it doesn't work even though it is executed on the listbox data table.
<DataTemplate x:Key="VerticalMenuItemTemplate">
<Canvas>
<TextBlock Text="{Binding AllowedRoles}">
</TextBlock>
<Rectangle Height="500" Width="500" Fill="Blue"></Rectangle></Canvas>
</DataTemplate>
In fact, as you can see from this little snippet, I have a direct setup along with the canvas. I don't see rect, which was just for testing, so it's almost like my template is being ignored.
<ListBox x:Name="VerticalContainer" Width="81" Height="Auto" HorizontalAlignment="Center" DataContext="{Binding Mode=OneWay, Source={StaticResource VerticalButtonCollectionDS}}" Padding="0,0,0,0" Canvas.Top="-14" ItemTemplate="{StaticResource VerticalMenuItemTemplate}">
source to share
This is a small example of what we are trying to do. I can get the contents of the "VerticalButton" and show it just fine, but we should be able to get the "AllowedRoles" dependency property in the template, because the end goal is to bind the element's visibility to that property (After creating the IValueConverter). We just can't wrap our heads around how to get to the AllowedRoles template from the ItemTemplate.
Here's the Page: xaml:
<UserControl x:Class="AnnexAMapTool.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mt="clr-namespace:AnnexAMapTool;assembly=AnnexAMapTool"
Width="400" Height="300">
<UserControl.Resources>
<mt:VerticalButtonCollection x:Key="TestCollection">
<mt:VerticalButton AllowedRoles="Test1, Test2" Content="VBContent"></mt:VerticalButton>
</mt:VerticalButtonCollection>
<Style x:Key="ListItemStyle" TargetType="ListBoxItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<StackPanel x:Name="Root" Orientation="Horizontal">
<TextBlock Foreground="Red" Text="{Binding AllowedRoles}"></TextBlock>
<Ellipse Width="20" Height="20" Fill="Blue"></Ellipse>
<ContentPresenter Content="{TemplateBinding Content}" Margin="5,5,5,5"/>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ListStyle" TargetType="ListBox">
<Setter Property="ItemContainerStyle" Value="{StaticResource ListItemStyle}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBox">
<Grid x:Name="Root">
<ItemsPresenter></ItemsPresenter>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White">
<ListBox Style="{StaticResource ListStyle}" ItemsSource="{StaticResource TestCollection}" />
</Grid>
</UserControl>
Here is the class code. Pretty basic .. comes from ButtonBase and has one DP defined. Also notice the collection class at the bottom.
Imports System.Windows.Controls.Primitives
Imports System.Collections.ObjectModel
Public Class VerticalButton
Inherits ButtonBase
Public Property AllowedRoles() As String
Get
Return GetValue(AllowedRolesProperty)
End Get
Set(ByVal value As String)
SetValue(AllowedRolesProperty, value)
End Set
End Property
Public Shared ReadOnly AllowedRolesProperty As DependencyProperty = DependencyProperty.Register("AllowedRoles", GetType(String), GetType(VerticalButton), New PropertyMetadata(New PropertyChangedCallback(AddressOf OnAllowedRolesChanged)))
Public Shared Sub OnAllowedRolesChanged(ByVal d As DependencyObject, ByVal args As DependencyPropertyChangedEventArgs)
Dim sender As VerticalButton = CType(d, VerticalButton)
sender.AllowedRoles = CStr(args.NewValue)
End Sub
End Class
Public Class VerticalButtonCollection
Inherits ObservableCollection(Of VerticalButton)
End Class
source to share