Home > OS >  Why combobox Items aren't displaying. C# WPF MVVM
Why combobox Items aren't displaying. C# WPF MVVM

Time:07-08

I have MainWindowViewModel and AccountViewModel. When I click 'Login' on my MainView:

  1. data about AvaliableExchages is fetched from database.
  2. Property CurrentViewModel is set to AccountViewModel.
  3. AvaliableExchanges property now has 2 strings ("Binance" and "Bitrue"). I can see it in debugger.

The problem is that I can't see them in the View. Combobox that binds its ItemsSource property to AvaliableExchanges Property doesn't show items.

MainViewModel:

internal class MainWindowViewModel : BaseViewModel
{
    private List<AppUser> _appUsers = new List<AppUser>();

    public List<AppUser> AppUsers
    {
        get => _appUsers;
        set => Set(ref _appUsers, value);
    }


    public BaseViewModel _currentViewModel;

    public BaseViewModel CurrentViewModel
    {
        get => _currentViewModel;
        set => Set(ref _currentViewModel, value);
    }


    public ICommand LoginCommand { get; }
    public bool CanLoginCommandExecute(object p) => true;
    public void OnLoginCommandExecuted(object p)
    {
        if (!string.IsNullOrEmpty(Username) && !string.IsNullOrEmpty(Password))
        {
            AppUsers = AppUser.GetAppUserByLoginAndPawwsord(Username, Password);
            if (AppUsers.Count > 0)
            {
                List<string> avaliableExchanges = new List<string>();
                foreach(var user in AppUsers)
                {
                    avaliableExchanges.Add(user.Exchange);
                }

                CurrentViewModel = new AccountViewModel(avaliableExchanges);
                LoginViewVisibility = Visibility.Collapsed;
                MainMenuVisibility = Visibility.Visible;                    
            }
        }
    }

    public MainWindowViewModel()
    {
        LoginCommand = new RelayCommand(OnLoginCommandExecuted, CanLoginCommandExecute);
    }
}

AccountViewModel:

internal class AccountViewModel : BaseViewModel
{
    private ObservableCollection<string> _avaliableExchanges;
    public ObservableCollection<string> AvaliableExchanges
    {
        get => _avaliableExchanges;
        set => Set(ref _avaliableExchanges, value);
    }

    public AccountViewModel()
    {
    }
    public AccountViewModel(List<string> avaliableExchanges)
    {
        AvaliableExchanges = new ObservableCollection<string>(avaliableExchanges);
    }

}

MainWindow:

<Window x:Class="ShababTrade.MainWindow"
        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:ShababTrade"
        xmlns:vm="clr-namespace:ShababTrade.ViewModels"
        xmlns:views="clr-namespace:ShababTrade.Views"
        xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
        mc:Ignorable="d"
        Title="Shabab Trade" Height="450" Width="800" 
        WindowState="Maximized" Background="#FF111111">
    
    <Window.DataContext>
        <vm:MainWindowViewModel/>
    </Window.DataContext>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        
        <Border Grid.Row="0" Grid.Column="0" BorderThickness="0.5" BorderBrush="DarkGray" Margin="5" CornerRadius="5"  Visibility="{Binding MainMenuVisibility}">
            <StackPanel Orientation="Horizontal" Margin="5">
                <Button Style="{StaticResource MainTabStyle}" Background="{Binding AccountTabBackground}"      Command="{Binding SelectMainMenuTabCommand}" CommandParameter="Account" Content="Account" />
                <Button Style="{StaticResource MainTabStyle}" Background="{Binding TradeHistoryTabBackground}" Command="{Binding SelectMainMenuTabCommand}" CommandParameter="History" Content="Trade History" />
                <Button Style="{StaticResource MainTabStyle}" Background="{Binding SpotTabBackground}"         Command="{Binding SelectMainMenuTabCommand}" CommandParameter="Spot"    Content="Spot" />
                <Button Style="{StaticResource MainTabStyle}" Background="{Binding AutoTradingTabBackground}"  Command="{Binding SelectMainMenuTabCommand}" CommandParameter="Auto"    Content="Auto Trading" Cursor="Hand" />
                <Button Style="{StaticResource MainTabStyle}" Background="{Binding FuturesTabBackground}"      Command="{Binding SelectMainMenuTabCommand}" CommandParameter="Futures" Content="Futures" Cursor="Hand" />
            </StackPanel>
        </Border>

        <Border Grid.Row="1" Grid.Column="0" BorderThickness="3" CornerRadius="5" Width="350" Height="430"
            BorderBrush="{StaticResource PrimaryColorBrush}" 
            Background="{StaticResource WhiteColorBrush}" Visibility="{Binding LoginViewVisibility}">

            <StackPanel>
                <TextBlock Margin="0 30 0 0"   FontSize="36" TextAlignment="Center" Text="Login"/>
                <TextBox   Margin="10 50 10 0" FontSize="20" materialDesign:HintAssist.Hint="Username" 
                       Text="{Binding Username}" Cursor="Arrow"/>
                <TextBox   Margin="10 40 10 0" FontSize="20" materialDesign:HintAssist.Hint="Password" 
                       Text="{Binding Password}" Cursor="Arrow"/>
                <Button    Margin="10 50 10 0" FontSize="20" Content="Login" Height="40" 
                       Background="{StaticResource SecondaryColorBrush}" 
                       Style="{StaticResource LoginButtonStyle}" 
                       Command="{Binding LoginCommand}" Cursor="Hand"/>
                <TextBlock Margin="0 20 0 0"   FontSize="16" TextAlignment="Center" >
                <Run Text="Not a member?"/>
                <Hyperlink Foreground="{StaticResource HyperlinkColorBrush}">Sign in</Hyperlink>
                </TextBlock>
            </StackPanel>

        </Border>

        <ContentControl Grid.Row="1" Grid.Column="0" Content="{Binding CurrentViewModel}" Visibility="{Binding MainMenuVisibility}">
            
        </ContentControl>
    </Grid>
</Window>

AccountView:

<UserControl x:Class="ShababTrade.Views.AccountView"
             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" 
             xmlns:local="clr-namespace:ShababTrade.Views"
             xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
             xmlns:views="clr-namespace:ShababTrade.ViewModels"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    
    <UserControl.DataContext>
        <views:AccountViewModel/>
    </UserControl.DataContext>

    <UserControl.Resources>
        <Style TargetType="TextBlock">
            <Setter Property="Foreground" Value="White"/>
        </Style>
    </UserControl.Resources>
    
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>

        <Border Grid.Row="0" Grid.Column="0" BorderThickness="0.5" BorderBrush="DarkGray" Margin="5" CornerRadius="5">
            <StackPanel>
                <StackPanel Orientation="Horizontal" Margin="1 10 0 0">
                    <TextBlock Text="Exchange:" Foreground="#D81D3C" FontSize="16" Margin="8 0 0 0"/>
                    <ComboBox Width="100" Height="25" Margin="5 0 0 0" HorizontalContentAlignment="Left" Padding="5 2 5 0" 
                              Background="#2D2D2D" Foreground="White" materialDesign:ColorZoneAssist.Mode="PrimaryDark"
                              ItemsSource="{Binding AvaliableExchanges, Mode=TwoWay}">
                    </ComboBox>
                </StackPanel>

                <ListView Grid.Row="1" Grid.Column="0" ItemsSource="{Binding Balances}" Foreground="White" >

                    <ListView.Resources>
                        <Style TargetType="{x:Type GridViewColumnHeader}" BasedOn="{StaticResource MaterialDesignFlatButton}">
                            <Setter Property="HorizontalContentAlignment" Value="Left" />
                        </Style>
                    </ListView.Resources>

                    <ListView.ItemContainerStyle>
                        <Style TargetType="ListViewItem" BasedOn="{StaticResource MaterialDesignGridViewItem}">
                            <Setter Property="Focusable" Value="false"/>
                        </Style>
                    </ListView.ItemContainerStyle>

                    <ListView.View>
                        <GridView>
                            <GridView.ColumnHeaderContainerStyle>
                                <Style BasedOn="{StaticResource {x:Type GridViewColumnHeader}}" TargetType="{x:Type GridViewColumnHeader}">
                                    <Setter Property="IsHitTestVisible" Value="False"/>
                                </Style>
                            </GridView.ColumnHeaderContainerStyle>
                            <GridView.ColumnHeaderTemplate>
                                <DataTemplate>
                                    <TextBlock Foreground="White" Text="{Binding}"/>
                                </DataTemplate>
                            </GridView.ColumnHeaderTemplate>
                            <GridViewColumn Header="Asset" DisplayMemberBinding="{Binding Asset}" Width="100"/>
                            <GridViewColumn Header="Free" DisplayMemberBinding="{Binding Free, StringFormat=N2}" Width="100"/>
                            <GridViewColumn Header="Locked" DisplayMemberBinding="{Binding Locked, StringFormat=N2}" Width="100"/>
                            <GridViewColumn Header="Total" DisplayMemberBinding="{Binding Total, StringFormat=N2}" Width="100"/>
                            <GridViewColumn Header="RubValue" DisplayMemberBinding="{Binding RubValue, StringFormat=N2}" Width="100"/>
                        </GridView>
                    </ListView.View>
                </ListView>
            </StackPanel>
        </Border>
    </Grid>
</UserControl>

CodePudding user response:

A UserControl must not explicitly set its own DataContext.

Remove

<UserControl.DataContext>
    <views:AccountViewModel/>
</UserControl.DataContext>

from the AccountView XAML, because it sets a different AccountViewModel instance than the one the control is expected to operate with.

Also note that it is poinless to set Mode=TwoWay on an ItemsSource Binding.

  • Related