tags:

views:

379

answers:

4

Hello, I'm new to the forum and very new to silverlight. Myself and my coworker are working on a custom application. We are building a menu system that will only display buttons if that useris in an assigned role. A new property was created to allow roles to be defined, and for testing purposes we are simply trying to assign that value, which is a string, to a textblock's text property. Some code is attached.

This is one of the items to be added to the collection. the allowedroles property is passing the string, this can be seen via 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 a list box, there are no errors, but binding does not work. I even attempted to do the binding in the listbox's data template. I appologize if this is confusing, I dont' know how to post something like this in easy to understand pieces.

Thanks

A: 
Bryant
Bit lacking on the link front there :)
TreeUK
Hmmm.. you're right. Where did they go?
Bryant
A: 
<MenuButton:VerticalButton AllowedRoles="test, test2">

The above line is where the allowedroles value is assigned. I'm creating a new instance of a button at that point.

Where I'm trying to bind allowed roles to the textblock is probably completely wrong, but it does not work even if it's being done in the listbox's datatemplate.

<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 rect setup along with the canvas. I don't see the rect, which was only for testing purposes, so it's almost like my template is being ignored. I have the list box set up as folows

<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}">
EliteMike
A: 

This is a small example of what we are trying to do. I can get the content of "VerticalButton" and display it just fine, but we need to be able to get at the "AllowedRoles" dependency property in the template because the end goal is to bind the visibility of the item to this property (After creating an IValueConverter). We just can't seem to wrap our heads around how to get to the AllowedRoles template from the listbox's 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's the Class code. Pretty basic.. derives from ButtonBase and has one DP defined. Also note 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
Tom
A: 

Ended up getting this working by doing the following. One of the tricks is that you can't use a converter on a template binding so you bind the DataContext of the object using a template binding and then use a regular binding to access that.

<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
Tom