【问题标题】:How to set the ItemSource of a Datagrid to a collection inside an object using MVVM如何使用 MVVM 将 Datagrid 的 ItemSource 设置为对象内的集合
【发布时间】:2011-11-08 21:53:33
【问题描述】:

我有一个包含 StrategyViewModel 列表的 ComboBox。 StrategyViewModel 内部有一个 StrategyParameterViewModels 的 ObservableCollection。我有一个名为 SelectedStrategy 的 StrategyViewModel,我绑定到组合框上的 SelectedItem 属性。当用户从组合框中选择一个策略时,我想将数据网格的 itemsource 设置为该策略内的 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>

这是策略视图模型:

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));
        }
    }   
}

这里是 StrategyParameter 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;
    }   
}

【问题讨论】:

    标签: c# wpf data-binding datagrid combobox


    【解决方案1】:

    问题是您正在尝试使用只读属性设置双向绑定。您需要为 SelectedStrategy.Parameters 添加一个 setter,或者在 datagrid itemssource 上使用 OneWay 绑定。

    【讨论】:

    • 天哪,我觉得自己很傻。我把它设置为oneway,它仍然没有工作。然后我意识到我没有在我的 SelectedStrategy 对象上实现 INotifyChanged。一旦我这样做了,一切都会很好。
    【解决方案2】:

    在我的脑海中,我认为您在 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/

    【讨论】:

      猜你喜欢
      • 2018-12-28
      • 1970-01-01
      • 2016-09-18
      • 1970-01-01
      • 1970-01-01
      • 2021-05-01
      • 2013-03-31
      • 1970-01-01
      • 2017-11-22
      相关资源
      最近更新 更多