WPF - The SelectedItem property of the ComboBox is not working correctly

5

Note: This question was the adapted translation of the original question, so all Updates of the original question are together in this text, sorry for that, but the time is short and I can not stop to make a better text, but thanks for the attention of all (Original question)

I've searched everywhere on the internet, but I did not find anything to help with my case.

I have several ComboBoxes for the project and I was looking for a solution to AutoComplete because the Toolkit did not please me, I found and applied the design along with the style for all of my ComboBoxes.

After that, SelectedItem stopped working, can anyone help me?

My ComboBox:

<ComboBox Name="CbOwnerType" Grid.Column="1" Grid.Row="2" ItemsSource="{Binding Path=OwnerTypes, Mode=OneWay}" SelectedItem="{Binding Owner.OwnerType, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectedValuePath="Id" DisplayMemberPath="Name" Margin="5,0,10,0" />

My style:

<Style TargetType="{x:Type ComboBox}">
    <Setter Property="FocusVisualStyle" Value="{x:Null}" />
    <Setter Property="Foreground" Value="Black" />
    <Setter Property="FontWeight" Value="ExtraBold" />
    <Setter Property="IsEditable" Value="False"/>
    <Setter Property="IsSynchronizedWithCurrentItem" Value="False" />
    <Setter Property="StaysOpenOnEdit" Value="True" />
    <Setter Property="SnapsToDevicePixels" Value="True"/>
    <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
    <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
    <Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ComboBox}">
                <Grid>
                    <ToggleButton Name="ToggleButton" Template="{StaticResource ComboBoxToggleButton}" Grid.Column="2" Focusable="True" IsChecked="{Binding Path=IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" ClickMode="Press" BorderThickness="0" />
                    <ContentPresenter Name="ContentSite" IsHitTestVisible="False" Content="{TemplateBinding SelectionBoxItem}" ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}" ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}" Margin="5,0,20,0" VerticalAlignment="Center" HorizontalAlignment="Left" />
                    <TextBox x:Name="PART_EditableTextBox" Style="{x:Null}" Template="{StaticResource ComboBoxTextBox}" HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="3,3,23,3" Focusable="True" Background="Transparent" Visibility="Hidden" IsReadOnly="{TemplateBinding IsReadOnly}" />
                    <Popup Name="Popup" Placement="Bottom" IsOpen="{TemplateBinding IsDropDownOpen}" AllowsTransparency="True" Focusable="False" PopupAnimation="Slide">
                        <Themes:SystemDropShadowChrome Margin="4,6,4,6" CornerRadius="4">
                            <Grid Name="DropDown" SnapsToDevicePixels="True" MinWidth="{TemplateBinding ActualWidth}" MaxHeight="{TemplateBinding MaxDropDownHeight}">
                                <Border x:Name="DropDownBorder" Background="{StaticResource WindowBackgroundBrush}" BorderThickness="1" BorderBrush="{StaticResource SolidBorderBrush}" />
                                <ScrollViewer Margin="4,6,4,6" SnapsToDevicePixels="True">
                                    <ItemsPresenter />
                                </ScrollViewer>
                            </Grid>
                        </Themes:SystemDropShadowChrome>
                    </Popup>
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="HasItems" Value="false">
                        <Setter TargetName="DropDownBorder" Property="MinHeight" Value="95"/>
                    </Trigger>
                    <Trigger Property="IsEnabled" Value="false">
                        <Setter Property="Foreground" Value="{StaticResource DisabledForegroundBrush}"/>
                    </Trigger>
                    <Trigger Property="IsGrouping" Value="true">
                        <Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
                    </Trigger>
                    <Trigger SourceName="Popup" Property="Popup.AllowsTransparency" Value="true">
                        <Setter TargetName="DropDownBorder" Property="CornerRadius" Value="4"/>
                        <Setter TargetName="DropDownBorder" Property="Margin" Value="0,2,0,0"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

My ToggleButton

<ControlTemplate x:Key="ComboBoxToggleButton" TargetType="{x:Type ToggleButton}" >
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition Width="20" />
        </Grid.ColumnDefinitions>
        <Border x:Name="Border" Grid.ColumnSpan="2" BorderBrush="{StaticResource LabPetsStandardColor}" BorderThickness="1" CornerRadius="5" />
        <Border Grid.Column="0" Margin="1" Background="Transparent" BorderBrush="{StaticResource NormalBorderBrush}" BorderThickness="0" CornerRadius="5,0,0,5" />
        <Path x:Name="Arrow" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center" Data="M 0 0 L 4 4 L 8 0 Z">
            <Path.Fill>
                <SolidColorBrush Color="Black" />
            </Path.Fill>
        </Path>
    </Grid>
    <ControlTemplate.Triggers>
        <Trigger Property="ToggleButton.IsMouseOver" Value="true">
            <Setter TargetName="Border" Property="Background" Value="{StaticResource LabPetsStandardColor}" />
        </Trigger>
        <Trigger Property="ToggleButton.IsChecked" Value="true">
            <Setter TargetName="Border" Property="Background" Value="{StaticResource LabPetsPressedStandardColor}" />
        </Trigger>
        <Trigger Property="IsEnabled" Value="False">
            <Setter TargetName="Border" Property="Background" Value="{StaticResource DisabledBackgroundBrush}" />
            <Setter TargetName="Border" Property="BorderBrush" Value="{StaticResource DisabledBorderBrush}" />
            <Setter Property="Foreground" Value="{StaticResource DisabledForegroundBrush}"/>
            <Setter TargetName="Arrow" Property="Fill" Value="{StaticResource DisabledForegroundBrush}" />
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

My TextBox

<Style x:Key="ComboBoxTextBox" TargetType="{x:Type TextBox}">
    <Setter Property="OverridesDefaultStyle" Value="True" />
    <Setter Property="AllowDrop" Value="True" />
    <Setter Property="MinWidth" Value="0" />
    <Setter Property="MinHeight" Value="0" />
    <Setter Property="FocusVisualStyle" Value="{x:Null}" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TextBox}">
                <ScrollViewer HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden" Background="#00FFFFFF" Name="PART_ContentHost" Focusable="False" VerticalAlignment="Center" VerticalContentAlignment="Center" Margin="0">
                    <ScrollViewer.Style>
                        <Style TargetType="ScrollViewer">
                            <Setter Property="OverridesDefaultStyle" Value="True" />
                        </Style>
                    </ScrollViewer.Style>
                </ScrollViewer>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Well, after a lot of trying, I found a solution, not the most beautiful and perfect, but it's a solution ...

If I put the property SelectedValue and Owner.OwnerTypeId , it works perfectly, but it's not the best practice, right?

My Combobox now:

<ComboBox Name="CbOwnerType" Grid.Column="1" Grid.Row="2" ItemsSource="{Binding Path=OwnerTypes, Mode=OneWay}" SelectedItem="{Binding Owner.OwnerType}" SelectedValue="{Binding Owner.OwnerTypeId}" SelectedValuePath="Id" DisplayMemberPath="Name" Margin="5,0,10,0" />

Well, this is the momentary solution, but could anyone explain to me why SelectedItem does not work as it should?

Note: When I change the selection, SelectedItem works perfectly, just not when I load view .

Well, it worked like I said, however it's going 4 times in my ViewModel , so I changed the properties a bit:

<ComboBox Name="CbOwnerType" Grid.Column="1" Grid.Row="2" ItemsSource="{Binding Path=OwnerTypes, Mode=OneWay}" SelectedItem="{Binding Owner.OwnerType}" SelectedValue="{Binding Owner.OwnerTypeId, Mode=OneTime}" SelectedValuePath="Id" DisplayMemberPath="Name" Margin="5,0,10,0" />

Well, for now, WPF can find OwnerTypeId and when I change the item, it only hits 2 times.

UPDATE

Okay, another strange fact ... Another ComboBox, with the same properties, less SelectedValue , is working perfectly ... I can not understand what happens.

Excuse me, I forgot to post my models.

Owner:

public class Owner
{
    public int Id { get; set; }
    public int OwnerTypeId { get; set; }
    public string Name { get; set; }
    public string Address { get; set; }
    public string FormatedPhone
    {
        get
        {
            if (this.Phone == null)
                return string.Empty;

            switch (this.Phone.Length)
            {
                case 11:
                    return Regex.Replace(this.Phone, @"(\d{2})(\d{4})(\d{4})", "($1) $2-$3");
                case 12:
                    return Regex.Replace(this.Phone, @"(\d{2})(\d{5})(\d{4})", "($1) $2-$3");
                default:
                    return this.Phone;
            }
        }
    }
    public string Phone { get; set; }
    public string CellPhone { get; set; }
    public string FormatedCellPhone
    {
        get
        {
            if (this.CellPhone == null)
                return string.Empty;

            switch (this.CellPhone.Length)
            {
                case 11:
                    return Regex.Replace(this.Phone, @"(\d{2})(\d{4})(\d{4})", "($1) $2-$3");
                case 12:
                    return Regex.Replace(this.Phone, @"(\d{2})(\d{5})(\d{4})", "($1) $2-$3");
                default:
                    return this.CellPhone;
            }
        }
    }
    public string Email { get; set; }
    public virtual OwnerType OwnerType { get; set; }
    public virtual ICollection<Animal> Animals { get; set; }

    public Owner()
    {
        this.OwnerType = new OwnerType();
        this.Animals = new List<Animal>();

        this.ErrorList = new StringBuilder();
    }

OwnerType:

public class OwnerType
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Owner> Owners { get; set; }

    public OwnerType()
    {
        this.Owners = new List<Owner>();
    }
}
    
asked by anonymous 18.12.2013 / 17:48

1 answer

4

Well, after a lot of trying, I found a palatative solution .

If I put the property SelectedValue and Owner.OwnerTypeId , it works perfectly, but it's just a palatable solution, since it's not working as it should.

My Combobox now:

<ComboBox Name="CbOwnerType" Grid.Column="1" Grid.Row="2" ItemsSource="{Binding Path=OwnerTypes, Mode=OneWay}" SelectedItem="{Binding Owner.OwnerType}" SelectedValue="{Binding Owner.OwnerTypeId}" SelectedValuePath="Id" DisplayMemberPath="Name" Margin="5,0,10,0" />

Note: When I change the selection, SelectedItem works perfectly, just not when I load view .

Well, ComboBox is going 4 times in my ViewModel , so I changed the properties a little:

<ComboBox Name="CbOwnerType" Grid.Column="1" Grid.Row="2" ItemsSource="{Binding Path=OwnerTypes, Mode=OneWay}" SelectedItem="{Binding Owner.OwnerType}" SelectedValue="{Binding Owner.OwnerTypeId, Mode=OneTime}" SelectedValuePath="Id" DisplayMemberPath="Name" Margin="5,0,10,0" />

For now, WPF can find OwnerTypeId and when I change the item, it goes to my ViewModel only 2 times.

    
23.12.2013 / 19:54