Trouble binding to property in uwp MVVM project

78 Views Asked by At

I am having a problem with binding from a view to a Viewmodel property.(UWP)

<AppBarToggleButton Label="Active" Icon="People"
                                    IsChecked="{x:Bind ViewModel.IsStatusBtnChecked, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                                    Click="{x:Bind ViewModel.empStautsBtnClicked}"/>

private bool isStatusBtnChecked = true;

    public bool IsStatusBtnChecked
    {
        get { return isStatusBtnChecked; }
        set { Set(ref isStatusBtnChecked, value); }
    }

When I try to get the value from a method to load combobox items the value is allways the default value

private List<string> depcombo;

    public List<string> Depcombo
    {
        get { return depcombo; }
        set
        {
            if (depcombo != value)
            {
                depcombo = value;
                OnPropertyChanged("Depcombo");
            }
        }
    }
    public async void GetDepCombo()
    {
        List<string> _dep = new List<string>();
        var data2 = await SqlServerDataService.GetAllEmployeesAsync();
        var depResult = (from emp in EmpItems
                         where emp.Status == IsStatusBtnChecked
                         select emp.Department).Distinct();
        foreach (var item in depResult)
        {
            if (item != null)
            {
                _dep.Add(item);
            }
        }
        Depcombo = _dep;
    }

When I load the data for Employyes it works fine

 public async Task LoadDataAsync(MasterDetailsViewState viewState)
    {
        EmpItems.Clear();
        var data = await SqlServerDataService.GetAllEmployeesAsync();
        data.Where(em => em.Status == IsStatusBtnChecked).ToList().ForEach(p => EmpItems.Add(p));
        if (viewState == MasterDetailsViewState.Both)
        {
            Selected = EmpItems.FirstOrDefault();
        }
    }

Some help will be much appreciated

1

There are 1 best solutions below

1
Nico Zhu On

When I try to get the value from a method to load combobox items the value is allways the default value

It's is confused that which is the combobox ItemsSource, if Depcombo is ComboBox ItemsSource, You have passed a new list instance to ItemsSource when you call GetDepCombo method.

Depcombo = _dep;

So, we need to set bind mode as OneWay(OneTime is default) that could response the object instance change.

<ComboBox
    Margin="0,120,0,0"
    ItemsSource="{x:Bind MainViewModel.Depcombo, Mode=OneWay}"
    >
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding}" />
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

If EmpItems is ComboBox ItemsSource, and it is ObservableCollection type. When you call LoadDataAsync, EmpItems clear the items fist, then add the new items. And this processing does not change the EmpItems instance object. it could works in onetime mode.

<ComboBox Margin="0,120,0,0" ItemsSource="{x:Bind MainViewModel.EmpItems}">
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding}" />
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>


<AppBarToggleButton Label="Active" Icon="People"
                                            x:Name="empStatusBtn"
                                            IsChecked="{x:Bind ViewModel.IsStatusBtnChecked, Mode=TwoWay}"
                                  Click="{x:Bind ViewModel.empStautsBtnClicked}"/>

public async void empStautsBtnClicked()
    {
        await LoadDataAsync(MasterDetailsViewState.Both);
    }

Looks like the problem is when the view is reloaded. Is there a way to refresh the view without reloading. When reloading the value of

private bool isStatusBtnChecked = true;

    public bool IsStatusBtnChecked
    {
        get { return isStatusBtnChecked; }
        set
        {
            if (isStatusBtnChecked != value)
            {
                isStatusBtnChecked = value;
                OnPropertyChanged("IsStatusBtnChecked");
            }
        }
    }

is true but the button isChecked property is false;