Enlace desde una propiedad personalizada

votos
0

Soy nuevo en el foro y muy nuevo en Silverlight. Yo y mi compañero de trabajo estamos trabajando en una aplicación personalizada. Estamos construyendo un sistema de menú que solo mostrará botones si ese usuario tiene un rol asignado. Se creó una nueva propiedad para permitir que se definan los roles, y para fines de prueba simplemente intentamos asignar ese valor, que es una cadena, a la propiedad de texto de un bloque de texto. Se adjunta algún código.

Este es uno de los artículos que se agregarán a la colección. la propiedad allowedroles está pasando la cadena, esto se puede ver a través del depurador.

<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

Los elementos se muestran en un cuadro de lista, no hay errores, pero el enlace no funciona. Incluso intenté hacer el enlace en la plantilla de datos de la lista. Me disculpo si esto es confuso, no sé cómo publicar algo así en piezas fáciles de entender.

Gracias

Publicado el 09/12/2008 a las 20:03
fuente por usuario
En otros idiomas...                            


4 respuestas

votos
0

Terminó haciendo que esto funcione haciendo lo siguiente. Uno de los trucos es que no puede usar un convertidor en un enlace de plantilla, por lo que vincula el DataContext del objeto utilizando un enlace de plantilla y luego utiliza un enlace regular para acceder a él.

<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
Respondida el 12/12/2008 a las 16:12
fuente por usuario

votos
0

Este es un pequeño ejemplo de lo que estamos tratando de hacer. Puedo obtener el contenido de "VerticalButton" y mostrarlo bien, pero tenemos que poder acceder a la propiedad de dependencia "AllowedRoles" en la plantilla porque el objetivo final es vincular la visibilidad del elemento a esta propiedad (Después creando un IValueConverter). Simplemente no podemos entender cómo llegar a la plantilla de AllowedRoles desde ItemTemplate de la lista.

Aquí está el 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>

Aquí está el código de la clase. Bastante básico. Deriva de ButtonBase y tiene un DP definido. También tenga en cuenta la clase de colección en la parte inferior.

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
Respondida el 10/12/2008 a las 21:56
fuente por usuario

votos
0
<MenuButton:VerticalButton AllowedRoles="test, test2"> 

La línea de arriba es donde se asigna el valor de Allowedroles. Estoy creando una nueva instancia de un botón en ese punto.

Donde estoy intentando vincular los roles permitidos al bloque de texto es probablemente completamente erróneo, pero no funciona incluso si se está haciendo en la plantilla de datos del cuadro de lista.

<DataTemplate x:Key="VerticalMenuItemTemplate">
            <Canvas>
            <TextBlock Text="{Binding AllowedRoles}">
            </TextBlock>
            <Rectangle Height="500" Width="500" Fill="Blue"></Rectangle></Canvas>
        </DataTemplate>

De hecho, como puede ver en este pequeño fragmento, tengo una configuración recta junto con el lienzo. No veo el rect, que era solo para fines de prueba, por lo que es casi como si mi plantilla fuera ignorada. Tengo el cuadro de lista configurado como 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}">
Respondida el 10/12/2008 a las 14:58
fuente por usuario

votos
0

Cuando utiliza la sintaxis de enlace, se vincula al DataContext del objeto. Entonces tu enlace:

<MenuButton:VerticalButton AllowedRoles="test, test2"> 
  <TextBlock Text="{Binding AllowedRoles}"></TextBlock>
</MenuButton:VerticalButton>

Básicamente, es decir, consígueme la propiedad "AllowedRoles" en mi DataContext. Dado que el contexto de datos es probablemente nulo (no lo vio configurado), no obtiene ningún valor en su bloque de texto.

Lo que probablemente quiera hacer es definir una plantilla para su MenuButton y luego en la plantilla puede decir:

<TextBlock Text="{TemplateBinding AllowedRoles}"></TextBlock>

Que se establecerá cuando aplique la plantilla al elemento.

Aquí hay algunos enlaces que publiqué en otro hilo sobre comprensión de plantillas y generic.xaml:

  • Control de personalización
  • Controles personalizables Skinnable
  • Ajustar los estilos predeterminados
  • 3 buenos enlaces en generic.xaml

¡Buena suerte!

Respondida el 09/12/2008 a las 23:46
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more