【问题标题】:How to bind Selected Items in MVVM如何在 MVVM 中绑定选定项
【发布时间】:2013-08-26 18:52:11
【问题描述】:

我正在使用 WPFMVVMDevExpress GridControl。我的 MainWindow.xaml 中有两个面板。 Panle1 有 Grid,Panel2 有 Textbox。我希望如果我从 Panel1 的网格中选择一个项目,它的名称应该显示在该 Panle2 文本框中。我写了代码,但它不起作用。你能帮我解决这个问题吗?

*在 Models 文件夹中的 NameModel 中我写道:*

private NameModelClass _selectedCustomer;
public NameModelClass SelectedCustomer
{
    get { return _selectedCustomer; }
    set
    {
        if (_selectedCustomer != value)
        {
            _selectedCustomer = value;
            LastName = value.LastName;
            OnPropertyChanged("SelectedCustomer");
        }
     }

    public List<Namess> ListPerson { get; set; }

    void CreateList()
    {
        ListPerson = new List<Namess>();
        for (int i = 0; i < 10; i++)
        {
            ListPerson.Add(new Namess(i));
        }
    }

    public class Namess
    {
        public Namess(int i)
        {
            FirstName = "FirstName" + i;
            LastName = "LastName" + i;
            Age = i * 10;
        }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int Age { get; set; }
    }
}

我在 MianWindow.xaml 中写道:

<dxdo:LayoutPanel Caption="Grid" Caption="Panel1" x:Name="abc1">
    <Grid>
        <dxg:GridControl x:Name="grid" Height="233" ItemsSource="{Binding ListPerson}" AutoGenerateColumns="AddNew" HorizontalAlignment="Left" VerticalAlignment="Top"   SelectedItem="{Binding SelectedNames}">
            <dxg:GridControl.View>
                <dxg:TableView ShowTotalSummary="True"/>
            </dxg:GridControl.View>
        </dxg:GridControl>
    </Grid>
</dxdo:LayoutPanel>

<dxdo:LayoutPanel Caption="Panel2" x:Name="abc1">
    <TextBox Width="166" Background="White" Height="33"  HorizontalAlignment="Right"  VerticalAlignment="Bottom"  Text="{Binding Path=LastName}"/>
</dxdo:LayoutPanel>

我是 MVVM 和 c# 的新手。如果您不清楚我的问题,请问我。谢谢。

【问题讨论】:

  • 您遇到的具体问题是什么?您的代码有几处问题,其中之一是您的绑定属性没有调用OnPropertyChangedFirstNameLastName)。 ListPerson 也应该是 ObservableCollection 而不是常规列表。检查您的输出窗口是否有任何绑定错误。
  • @PoweredByOrange 我想在 Panel2 的文本框中显示从网格中选择的项目

标签: c# .net wpf data-binding mvvm


【解决方案1】:

我是这样做的:

private Namess _selectedCustomer;
public Namess SelectedCustomer
{
    get { return _selectedCustomer; }
    set
    {
        if (_selectedCustomer != value)
        {
            _selectedCustomer = value;
            OnPropertyChanged("SelectedCustomer");
        }
     }

    public List<Namess> ListPerson { get; set; }

    void CreateList()
    {
        ListPerson = new List<Namess>();
        for (int i = 0; i < 10; i++)
        {
            ListPerson.Add(new Namess(i));
        }
    }

    public class Namess : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
                handler(this, new PropertyChangedEventArgs(propertyName));
        }

        public Namess(int i)
        {
            FirstName = "FirstName" + i;
            LastName = "LastName" + i;
            Age = i * 10;
        }
        public string FirstName { get; set; }
        private string _lastName;
        public string LastName 
        { 
            get
            {
                return _lastName;
            }
            set
            {
                if(value==_lastName)
                    return;
                _lastName=value;
                OnPropertyChanged("LastName");
            }
        }
        public int Age { get; set; }
    }
}

在你看来:

<dxdo:LayoutPanel Caption="Grid" Caption="Panel1" x:Name="abc1">
    <Grid>
        <dxg:GridControl x:Name="grid" Height="233" ItemsSource="{Binding ListPerson}" AutoGenerateColumns="AddNew" HorizontalAlignment="Left" VerticalAlignment="Top" SelectedItem="{Binding SelectedNames,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}">
            <dxg:GridControl.View>
                <dxg:TableView ShowTotalSummary="True"/>
            </dxg:GridControl.View>
        </dxg:GridControl>
    </Grid>
</dxdo:LayoutPanel>

<dxdo:LayoutPanel Caption="Panel2" x:Name="abc1">
    <TextBox Width="166" Background="White" Height="33"  HorizontalAlignment="Right" VerticalAlignment="Bottom"  Text="{Binding Path=SelectedCustomer.LastName,Mode=OneWay,UpdateSourceTrigger=PropertyChanged}"/>
</dxdo:LayoutPanel>

基本上我将 SelectedCustomer 的类型更改为项目集合之一。在视图中,您可以将 TextBox 的绑定直接设置为 SelectedCustomer 的属性。

【讨论】:

  • 在 GridControl 上设置 SelectedItem="{Binding SelectedName,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" 和 SelectionMode="Row" 非常适合我。
【解决方案2】:

您似乎忘记为“LastName”字符串引发 INPC (INotifyPropertyChanged) 事件。

所以试试这个(更改在下面的设置器中):

public NameModelClass SelectedCustomer
    {
    get { return _selectedCustomer; }
    set
        {
        if (_selectedCustomer != value)
            {
            _selectedCustomer = value;
            LastName = value.LastName;
            OnPropertyChanged("SelectedCustomer");
            OnPropertyChanged("LastName");   //<-- new 
            }
        }
    }

您必须发送 INPC,以便绑定知道更新为新值。除非您引发该事件,否则显示的绑定不会“获取” LastName 的新值。

【讨论】:

  • 是什么?你添加新行了吗?另外,我强烈建议初学者不要使用第三方控件。
  • 哦,对不起!我的意思是我已经用你提供的代码行更新了我的代码。但是还是不行。
  • 啊。您的 SelectedItem 需要绑定到“SelectedCustomer”而不是“SelectedNames”。
  • 在 "LastName" 属性 getter 上放置一个断点,并查看在从网格中选择一个客户名称后它获取的值(如果有)。这是现在唯一能给你任何信息的东西。
【解决方案3】:

你试过了吗:

SelectedItem="{Binding SelectedNames, Mode=TwoWay}"

仔细研究后,您的主要 Names 类可以实现 INotifyPropertyChanged

每个属性都会在 ahem 更改时引发属性更改事件。

还使用可观察集合,因此当您添加和删除项目时,它也会引发更改。

这样,通知更改系统接收到属性更改的通知以通过绑定相应地更改视图。

【讨论】:

    猜你喜欢
    • 2021-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-18
    • 1970-01-01
    相关资源
    最近更新 更多