WPF - The Selecteditem property, from Combobox, is not working properly

Asked

Viewed 839 times

5

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


I’ve searched every corner of the Internet, but I haven’t found anything to help my case.

I have several Comboboxes for the project and I was looking for a solution for the Autocomplete, because the Toolkit did not please me, I found and applied in the project, along with the style for all my Comboboxes.

After that, the SelectedItem stopped working, someone can 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, it’s not the most beautiful and perfect, but it’s a solution...

If I put the property SelectedValue and the Owner.OwnerTypeId, works perfectly, but is 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, that’s the momentary solution, but someone could explain to me why SelectedItem does not work as it should ?

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

Well, it worked like I said, but it’s going four times in mine ViewModel, so I switched properties a little 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, the WPF can find the OwnerTypeId and when I change item, it hits only 2 times.

UPDATING

Okay, another weird fact... Another Combobox, with the same properties, less SelectedValue, is working perfectly... I can’t 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>();
    }
}
  • Because it’s not a perfect solution, it’s a lame solution, and for me, it’s not enough... I would like to understand why it does not work for this situation/context SelectedItem and for others it works.

1 answer

4

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

If I put the property SelectedValue and the Owner.OwnerTypeId, works perfectly, but it’s just a lame solution, because it’s not working the way 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, the SelectedItem works perfectly, just not when I carry the view.

Well, the ComboBox is going 4 times in mine ViewModel, so I switched properties a little 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" />

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

Browser other questions tagged

You are not signed in. Login or sign up in order to post.