WPF MVVM ComboBox привязка данных - PullRequest
0 голосов
/ 30 января 2019

Я пытаюсь создать простое приложение WPF и привязать данные к списку, но мне не повезло.Мой PeriodList заполняется нормально, но не привязывается к списку.Нужно ли устанавливать DataContext в XAML или в коде позади?Пожалуйста, помогите, я очень запутался.

Вот мой XAML

<UserControl x:Class="FinancialControlApp.KeyClientReportView"
             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:FinancialControlApp"
             mc:Ignorable="d" 
             d:DesignHeight="300" Width="630">

    <UserControl.Resources>
        <!-- DataTemplate (View) -->
        <DataTemplate DataType="{x:Type local:KeyClientReportModel}">
        </DataTemplate>
    </UserControl.Resources>

    <DockPanel Margin="20">
        <DockPanel DockPanel.Dock="Top" VerticalAlignment="Center">
            <TextBlock Margin="10,2" DockPanel.Dock="Left" Text="Start Period" VerticalAlignment="Center" />

            <ComboBox Name="cmbStartPeriod" Margin="10,2" Width="112" VerticalAlignment="Center" ItemsSource="{Binding PeriodList}">
            </ComboBox>

            <TextBlock Margin="10,2" DockPanel.Dock="Left" Text="End Period" VerticalAlignment="Center" />

            <ComboBox Name="cmbEndPeriod" Margin="10,2" Width="112" VerticalAlignment="Center" ItemsSource="{Binding PeriodList}" />

            <!--<Button Content="Save Product" DockPanel.Dock="Right" Margin="10,2" VerticalAlignment="Center"
                        Command="{Binding Path=SaveProductCommand}" Width="100" />-->

            <Button Content="Run" DockPanel.Dock="Left" Margin="10,2" 
                        Command="{Binding Path=GetProductCommand}" IsDefault="True" Width="100" />
        </DockPanel>

        <!--<ContentControl Margin="10" Content="{Binding Path=PeriodName}" />-->
        <ContentControl Margin="10"></ContentControl>
    </DockPanel>
</UserControl>

Вот моя модель

     namespace FinancialControlApp
    {
       public class KeyClientReportModel : ObservableObject
       {

        private string _periodName;

        public string PeriodName
        {
            get { return _periodName; }
            set
            {
                if (value != _periodName)
                {
                    _periodName = value;
                    OnPropertyChanged("PeriodName");
                }
            }
        }

        List<KeyClientReportModel> _periodList = new List<KeyClientReportModel>();

        public List<KeyClientReportModel> PeriodList
        {
            get { return _periodList; }
            set
            {
                _periodList = value;
                OnPropertyChanged("PeriodList");
            }
        }
      }
}

А вот моя ViewModel

    namespace FinancialControlApp
{
    public class KeyClientReportViewModel : ObservableObject, IPageViewModel
    {
        private KeyClientReportModel _currentPeriod;
        private ICommand _getReportCommand;
        private ICommand _saveReportCommand;

        public KeyClientReportViewModel()
        {
            GetPeriod();
        }

        public string Name
        {
            get { return "Key Client Report"; }
        }

        public ObservableCollection<KeyClientReportModel> _periodName;
        public ObservableCollection<KeyClientReportModel> PeriodName
        {
            get { return _periodName; }
            set
            {
                if (value != _periodName)
                {
                    _periodName = value;
                    OnPropertyChanged("PeriodName");
                }
            }
        }

        private void GetPeriod()
        {
            DataSet ds = new DataSet();
            DataTable dt = new DataTable();
            Helper_Classes.SQLHelper helper = new Helper_Classes.SQLHelper();

            ds = helper.getPeriod();
            dt = ds.Tables[0];
            PeriodName = new ObservableCollection<KeyClientReportModel>();
            foreach (DataRow dr in dt.Rows)
            {
                var period = dr["Period"].ToString();
                if (period != null)
                {
                    PeriodName.Add(new KeyClientReportModel { PeriodName = period });
                }
                //p.PeriodName = dr["Period"].ToString();           
            }
        }
}
}

ОБНОВЛЕНИЕ: Итак, я присоединяю конвертер значений, чтобы взломать отладчик, и вот что я вижу.Я вижу

Я вижу 5 пунктов в списке

Ответы [ 2 ]

0 голосов
/ 30 января 2019

Это может вам помочь

------ View

<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        <!-- To get the ViewModel -->
        xmlns:viewmodels="clr-namespace:WpfApp1.ViewModels"
        Title="MainWindow">
    <Window.DataContext>
        <!-- Assigning the ViewModel to the View -->
        <viewmodels:MainWindowViewModel />
    </Window.DataContext>
    <DockPanel VerticalAlignment="Center"
               DockPanel.Dock="Top">
        <TextBlock Margin="10,2"
                   VerticalAlignment="Center"
                   DockPanel.Dock="Left"
                   Text="Start Period" />
        <ComboBox Name="cmbStartPeriod"
                  Width="112"
                  Margin="10,2"
                  VerticalAlignment="Center"
                  ItemsSource="{Binding PeriodName}" // Items in the ViewModel 
                  DisplayMemberPath="Name"/> // Property to display
    </DockPanel>
</Window>

------- ViewModel

public class MainWindowViewModel
{
    public MainWindowViewModel()
    {
        var items = new List<KeyClientReportModel>
        {
            new KeyClientReportModel
            {
                Name = "First",
                Value = 1
            },
            new KeyClientReportModel
            {
                Name = "Second",
                Value = 1
            }
        };

        PeriodName = new ObservableCollection<KeyClientReportModel>(items);
    }

    // You don't need to notify changes here because ObservableCollection 
    // send a notification when a change happens. 
    public ObservableCollection<KeyClientReportModel> PeriodName { get; set; }

}

public class KeyClientReportModel
{
    public int Value { get; set; }
    public string Name { get; set; }
}
0 голосов
/ 30 января 2019

Изменить

ItemsSource="{Binding KeyClientReportModel.PeriodList}"

На:

ItemsSource="{Binding PeriodList}"

Убедитесь, что для ViewModel установлено свойство DataContext вашего просмотра.

Установитекомбинированный список DisplayMemberPath со свойством Name вашего KeyClientReportViewModel класса.

Или, альтернативно, переопределите метод .ToString() внутри класса KeyClientReportViewModel, чтобы обеспечить отображаемый текст элемента Combobox.

...