Nick Posey
Nick Posey

Reputation: 127

WPF ComboBox Item Binding with XAML Values

How can I select the item of a combobox that I have defined in XAML through binding?

For example, I have a combobox:

        <ComboBox x:Name="cboPayFrequency" Grid.Column="4" Grid.Row="7" Tag="c" Style="{StaticResource ShadedComboBox}" SelectedValue="{Binding Path=PayFrequency, Converter={StaticResource payFrequencyConverter}}" VerticalAlignment="Center">
            <ComboBoxItem>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Foreground="Green" Text="{x:Static p:Resources.Weekly}" />
                </StackPanel>
            </ComboBoxItem>
            <ComboBoxItem>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Foreground="Blue" Text="{x:Static p:Resources.BiWeekly}" />
                </StackPanel>
            </ComboBoxItem>
            <ComboBoxItem IsSelected="True">
                <StackPanel Orientation="Horizontal">
                    <TextBlock Foreground="Orange" Text="{x:Static p:Resources.Monthly}" />
                </StackPanel>
            </ComboBoxItem>
            <ComboBoxItem>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Foreground="Red" Text="{x:Static p:Resources.SemiMonthly}" />
                </StackPanel>
            </ComboBoxItem>
            <ComboBoxItem>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Foreground="YellowGreen" Text="{x:Static p:Resources.Quarterly}" />
                </StackPanel>
            </ComboBoxItem>
            <ComboBoxItem>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Foreground="Purple" Text="{x:Static p:Resources.SemiAnnually}" />
                </StackPanel>
            </ComboBoxItem>
            <ComboBoxItem>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Foreground="HotPink" Text="{x:Static p:Resources.Annually}" />
                </StackPanel>
            </ComboBoxItem>
        </ComboBox>

But each combobox item is actually just a stackpanel with a textbox. I did that because I wanted each item to be a different color to stand out, but how can I actually select one of those values through binding?

Thanks

Upvotes: 0

Views: 759

Answers (2)

mm8
mm8

Reputation: 169200

I did that because I wanted each item to be a different color to stand out, but how can I actually select one of those values through binding?

Set the SelectedValuePath and bind the SelectedValue property to a string:

<ComboBox x:Name="cboPayFrequency" ... SelectedValue="{Binding Value}" 
                                       SelectedValuePath="Content.Children[0].Text">

View Model:

public class ButtonViewModel
{
    public string Value { get; set; } = "BiWeekly";
}

Upvotes: 1

RAKESH KUMAR SAHU
RAKESH KUMAR SAHU

Reputation: 130

I have create a working sample for the above issue.

<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApplication1"
        xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
        xmlns:Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero" x:Class="WpfApplication1.MainWindow"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">

    <Window.Resources>       
        <Style TargetType="{x:Type ComboBoxItem}">
            <Setter Property="SnapsToDevicePixels" Value="true" />
            <Setter Property="OverridesDefaultStyle" Value="true" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ComboBoxItem}">
                        <Border x:Name="Border" Padding="2" SnapsToDevicePixels="true" Background="Transparent">                            
                            <ContentPresenter />
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="Content" Value="Weekly">
                                <Setter Property="TextBlock.Foreground" TargetName="Border" Value="Green"/>
                            </Trigger>
                            <Trigger Property="Content" Value="BiWeekly">
                                <Setter Property="TextBlock.Foreground" TargetName="Border" Value="Blue"/>
                            </Trigger>
                            <Trigger Property="Content" Value="Monthly">
                                <Setter Property="TextBlock.Foreground" TargetName="Border" Value="Orange"/>
                            </Trigger>
                            <Trigger Property="Content" Value="SemiMonthly">
                                <Setter Property="TextBlock.Foreground" TargetName="Border" Value="Red"/>
                            </Trigger>
                            <Trigger Property="Content" Value="Quarterly">
                                <Setter Property="TextBlock.Foreground" TargetName="Border" Value="YellowGreen"/>
                            </Trigger>
                            <Trigger Property="Content" Value="SemiAnnually">
                                <Setter Property="TextBlock.Foreground" TargetName="Border" Value="Purple"/>
                            </Trigger>
                            <Trigger Property="Content" Value="Annually">
                                <Setter Property="TextBlock.Foreground" TargetName="Border" Value="HotPink"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>

    <Window.DataContext>
        <local:MainViewModel/>
    </Window.DataContext>

    <Grid Background="{Binding BackgroundColor}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">       
        <ComboBox x:Name="cboPayFrequency" Grid.Column="4" Grid.Row="7" VerticalAlignment="Center" ItemsSource="{Binding PayFrequencies}" SelectedValue="{Binding SelectedFrequency}">
        </ComboBox>
    </Grid>
</Window>


public class MainViewModel : INotifyPropertyChanged
    {
        private List<string> _payFrequencies;

        public List<string> PayFrequencies
        {
            get { return _payFrequencies; }
            set { _payFrequencies = value; NotifyPropertyChanged("PayFrequencies"); }
        }

        private string _selectedFrequency;

        public event PropertyChangedEventHandler PropertyChanged;

        public string SelectedFrequency
        {
            get { return _selectedFrequency; }
            set { _selectedFrequency = value; NotifyPropertyChanged("SelectedFrequency"); }
        }

        public MainViewModel()
        {
            Initialize();
        }

        public void NotifyPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        private void Initialize()
        {
            PayFrequencies = new List<string>();
            PayFrequencies.Add("Weekly");
            PayFrequencies.Add("BiWeekly");
            PayFrequencies.Add("Monthly");
            PayFrequencies.Add("SemiMonthly");
            PayFrequencies.Add("Quarterly");
            PayFrequencies.Add("SemiAnnually");
            PayFrequencies.Add("Annually");

            SelectedFrequency = "Annually";
        }
    }

Please let me know if this will resolve your issue or not.

Upvotes: 0

Related Questions