Frage

I have the following Usercontrol which I am using / referencing inside another xaml file -

<UserControl x:Class="WpfApplication2.MutuallyExclusiveToggleControl"
         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" 
         x:Name="SpecialToggleControl"
         d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
    <Style TargetType="{x:Type ListBoxItem}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate>
                    <ToggleButton Content="{TemplateBinding ContentControl.Content}"
                        Background="{Binding ElementName=SpecialToggleControl, Path=TileBackground}"          
                        IsChecked="{Binding Path=IsSelected, RelativeSource={RelativeSource TemplatedParent}}" 
                                  Name="toggleButton"/>
                    <ControlTemplate.Triggers>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</UserControl.Resources>
<ListBox x:Name="_listBox"
    SelectionChanged="ListBoxSelectionChanged"
    SelectedItem="{Binding ElementName=SpecialToggleControl, Path=SelectedItem}"
    SelectionMode="Single" ItemsSource="{Binding ElementName=SpecialToggleControl, Path=ItemsSource}">
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <UniformGrid Columns="{Binding ElementName=SpecialToggleControl, Path=ColumnCount}"/>
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
</ListBox>

Question: How do I access the ToggleButton's content (which is in ControlTemplate) from the place where I am using this UserControl. For ex: say, based on the Content, I want to set the background color. I do not want to do this from inside the UserControl. I want to achieve this from the place where I am using this UserControl

Thanks in advance.

War es hilfreich?

Lösung 2

Ok, I will answer it. The thing was instead of ControlTemplate we should modify the ListBox's ItemTemplate and apply the same ControlTemplate as a DataTemplate.

<ListBox x:Name="_listBox"
    SelectedItem="{Binding ElementName=SpecialToggleControl, Path=SelectedItem}"
    SelectionMode="Single" 
    ItemsSource="{Binding ElementName=SpecialToggleControl, Path=ItemsSource}">
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <UniformGrid Columns="{Binding ElementName=SpecialToggleControl, Path=ColumnCount}" Background="Beige"/>
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <ToggleButton Content="{TemplateBinding ContentControl.Content}" 
                          IsChecked="{Binding RelativeSource={RelativeSource Mode=FindAncestor, 
                                            AncestorType={x:Type ListBoxItem}},Path=IsSelected}" 
                          Name="toggleButton"/>
        </DataTemplate>
    </ListBox.ItemTemplate>

    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Setter Property="HorizontalContentAlignment" Value="Stretch" />
            <Setter Property="VerticalContentAlignment" Value="Stretch" />
        </Style>
    </ListBox.ItemContainerStyle>

</ListBox>

MainWindow.xaml (where I used this Control): (The converter "cc" will now conditionally apply the colour)

                <WpfApplication2:MutuallyExclusiveToggleControl.Resources>
                <Style TargetType="{x:Type ToggleButton}">
                    <Style.Setters>
                        <Setter Property="Background" Value="{Binding Converter={StaticResource cc}}"></Setter>
                    </Style.Setters>                    
                </Style>
            </WpfApplication2:MutuallyExclusiveToggleControl.Resources>

Converter Code:

public class ColourConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if((string)value == "Buy")
        {
            return Brushes.Blue;
        }

        if ((string)value == "Sell")
        {
            return Brushes.Red;
        }

        return Brushes.White;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Andere Tipps

You can create Dependency Properties for the Properties you want to access from where you use your UserControl. With that you can bind values from outside to specific properties in your ControlTemplate.

Your code for setting the Button's Content from outside would look something like this:

Dependency Property (in your UserControl's code-behind):

public string ButtonContent
{
    get { return (string)GetValue(ButtonContentProperty); }
    set { SetValue(ButtonContentProperty, value); }
}

public static readonly DependencyProperty ButtonContentProperty =
    DependencyProperty.Register("ButtonContent", typeof(string), typeof(TestButton), new PropertyMetadata("Test"));

After you bound it to the Property in your Usercontrol, you could create your Usercontrol like that and take the content you want from your ViewModel for example (assuming you're using MVVM):

<wpfApplication2:TestButton ButtonContent="{Binding TestContentFromViewModel}"></wpfApplication2:TestButton>

You can do that for every Property in your UserControl you want.

For additional information about Dependency Properties see here.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top