Как установить ItemSource Datagrid в коллекцию внутри объекта, используя MVVM - PullRequest
1 голос
/ 09 ноября 2011

У меня есть ComboBox, который содержит список StrategyViewModels.Внутри StrategyViewModel имеется ObservableCollection StrategyParameterViewModels.У меня есть StrategyViewModel с именем SelectedStrategy, который я привязал к свойству SelectedItem в выпадающем списке.Когда пользователь выбирает стратегию из ComboBox, я хотел бы установить источник элементов сетки данных для StrategyParameters внутри этой стратегии.Я пробовал все разные способы, но, похоже, ничего не работает.

Вот XAML:

<ComboBox Height="23" Margin="0,12,0,0" Name="cbxStrats" VerticalAlignment="Top" ItemsSource="{Binding Strategies}" DisplayMemberPath="Name" SelectedItem="{Binding Path=SelectedStrategy,Mode=TwoWay}" />

 <DataGrid AutoGenerateColumns="False" Margin="12,97,14,35" Name="dgSettings" ItemsSource="{Binding SelectedStrategy.Parameters, Mode=TwoWay}">
        <DataGrid.Columns>
            <DataGridTextColumn Header="Name"  Binding="{Binding Path=Name}" IsReadOnly="True"/>
            <DataGridTextColumn Header="Value" Binding="{Binding Path=Value}" IsReadOnly="False"/>
        </DataGrid.Columns>
    </DataGrid>

Вот стратегия ViewModel:

public class StrategyViewModel : ViewModelBase
{
    public StrategyObject Strategy { get; set; }

    public int Id
    {
        get { return Strategy.Id; }
        set 
        {
            if (value == Strategy.Id)
                return;
            Strategy.Id = value;
            OnPropertyChanged("Id");
        }
    }

    public string Name
    {
        get { return Strategy.Name; }
        set 
        {
            if (value == Strategy.Name)
                return;
            Strategy.Name = value;
            OnPropertyChanged("Name");
        }
    }

    public ObservableCollection<StrategyParameterViewModel> Parameters { get { return _parameters; } }
    public ObservableCollection<StrategyParameterViewModel> _parameters;

    public StrategyViewModel()
    {
        Strategy = new StrategyObject();
        _parameters = new ObservableCollection<StrategyParameterViewModel>();
    }

    public StrategyViewModel(StrategyObject o, IEnumerable<StrategyParameterObject> pms)
    {
        Strategy = o;
        _parameters = new ObservableCollection<StrategyParameterViewModel>();
        foreach (StrategyParameterObject s in pms)
        {
            _parameters.Add(new StrategyParameterViewModel(s));
        }
    }   
}

А воттакое стратегияПараметр ViewModel:

public class StrategyParameterViewModel : ViewModelBase
{
    public StrategyParameterObject StrategyParameter { get; set; }

    public int Id
    {
        get { return StrategyParameter.Id; }
        set 
        {
            if (value == StrategyParameter.Id)
                return;
            StrategyParameter.Id = value;
            OnPropertyChanged("Id");
        }
    }

    public int StrategyId
    {
        get { return StrategyParameter.StrategyId; }
        set 
        {
            if (value == StrategyParameter.StrategyId)
                return;
            StrategyParameter.StrategyId = value;
            OnPropertyChanged("StrategyId");
        }
    }

    public string Name
    {
        get { return StrategyParameter.Name; }
        set 
        {
            if (value == StrategyParameter.Name)
                return;
            StrategyParameter.Name = value;
            OnPropertyChanged("Name");
        }
    }

    public string Value
    {
        get { return StrategyParameter.Value; }
        set 
        {
            if (value == StrategyParameter.Value)
                return;
            StrategyParameter.Value = value;
            OnPropertyChanged("Value");
        }
    }

            public StrategyParameterViewModel() 
    {
        StrategyParameter = new StrategyParameterObject();
    }

    public StrategyParameterViewModel(StrategyParameterObject o) 
    {
        StrategyParameter = o;
    }   
}

Ответы [ 2 ]

1 голос
/ 09 ноября 2011

Проблема в том, что вы пытаетесь настроить двухстороннее связывание со свойством только для чтения.Вам нужно либо добавить установщик для SelectedStrategy.Parameters, либо использовать привязку OneWay для источника элементов сетки данных.

1 голос
/ 09 ноября 2011

Вдобавок ко всему, я не думаю, что вы делаете что-то не так с вашим XAML.

Связывание данных, как известно, сложно.Я предлагаю добавить PresentationTraceSources, чтобы получить больше отладочной информации о том, что найдено.Это доставит несколько строк данных о результатах привязки в ваше окно вывода.

    <ComboBox Height="23" Margin="0,12,0,0" Name="cbxStrats" VerticalAlignment="Top" DisplayMemberPath="Name">
        <ComboBox.ItemsSource>
            <Binding Path="Strategies" PresentationTraceSources.TraceLevel="High"/>
        </ComboBox.ItemsSource>
        <ComboBox.SelectedItem>
            <Binding Path="SelectedStrategy" Mode="TwoWay" PresentationTraceSources.TraceLevel="High"/>
        </ComboBox.SelectedItem>
    </ComboBox>

    <DataGrid AutoGenerateColumns="False" Margin="12,97,14,35" Name="dgSettings">
        <DataGrid.ItemsSource>
            <Binding Path="SelectedStrategy.Parameters" Mode="TwoWay" PresentationTraceSources.TraceLevel="High"/>
        </DataGrid.ItemsSource>
        <DataGrid.Columns>
            <DataGridTextColumn Header="Name"  Binding="{Binding Path=Name}" IsReadOnly="True"/>
            <DataGridTextColumn Header="Value" Binding="{Binding Path=Value}" IsReadOnly="False"/>
        </DataGrid.Columns>
    </DataGrid>

Кроме того, WPF Inspector может помочь, так как вы можете настраивать выражения привязки данных в реальном времени при запуске реального приложения.http://wpfinspector.codeplex.com/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...