【问题标题】:WPF MVVM Combobox bindingWPF MVVM 组合框绑定
【发布时间】:2017-07-31 17:23:22
【问题描述】:

我在 MVVM 模式中创建了一个组合框和 im 绑定,但我的属性没有绑定到视图,我对 itemsourceselectvalue 感到困惑。 我可以对 view.xaml 进行哪些更改?我猜我的模型和视图模型中的其余代码是完美的。

这是我的模特

namespace screensaver.Models {
    class ConfigurationModel {
        public int _resolution;

        private ObservableCollection < ConfigurationModel > Resolution {
            get {
                return Resolution;
            }
            set {
                Resolution = value;
            }
        }

        public ConfigurationModel() {
            Resolution = new ObservableCollection < ConfigurationModel > () {
                new ConfigurationModel() {
                    _resolution = 360 * 720
                },
                new ConfigurationModel() {
                    _resolution = 720 * 1080
                },
                new ConfigurationModel() {
                    _resolution = 1080 * 2060
                }
            };
        }
    }
}

这是我的视图模型

namespace screensaver.ViewModels {
    class ConfigurationViewModel {
        private ObservableCollection < ConfigurationModel > _resolution;

        public ObservableCollection < ConfigurationModel > Resolution {
            get {
                return Resolution;
            }
            set {
                Resolution = value;
            }
        }

    }
}

这是我的 View xaml 代码

<Window x:Class="screensaver.Views.ConfigurationWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:ViewModels="clr-namespace:screensaver.ViewModels" Title="ConfigurationWindow"
Height="1000" Width="500">
    <Grid>
        <Label Content="Display" HorizontalAlignment="Left" Margin="7,12,0,0" VerticalAlignment="Top" />
        <ComboBox HorizontalAlignment="Left" Margin="322,14,0,0" VerticalAlignment="Top" Width="120" />
        <ComboBox ItemsSource="{Binding Resolution}" SelectedItem="{Binding 
       Resolution, Mode=TwoWay}" DisplayMemberPath="{Binding Resolution}" HorizontalAlignment="Left" Margin="74,13,0,0" VerticalAlignment="Top" Width="120" />
        <Label Content="Resolution" HorizontalAlignment="Left" Margin="250,13,0,0" VerticalAlignment="Top" />
        <Button Content="Save" HorizontalAlignment="Left" Margin="80,362,0,0" VerticalAlignment="Top" Width="75" />
        <Button Content="Close" HorizontalAlignment="Left" Margin="350,360,0,0" VerticalAlignment="Top" Width="75" />
        <Label Content="Height" HorizontalAlignment="Left" Margin="72,178,0,0" VerticalAlignment="Top" />
        <TextBox HorizontalAlignment="Left" Height="23" Margin="140,181,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" />
        <Label Content="Width" HorizontalAlignment="Left" Margin="290,175,0,0" VerticalAlignment="Top" />
        <TextBox HorizontalAlignment="Left" Height="23" Margin="346,179,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" />
        <Label Content="Top" HorizontalAlignment="Left" Margin="76,253,0,0" VerticalAlignment="Top" />
        <TextBox HorizontalAlignment="Left" Height="23" Margin="140,255,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" />
        <Label Content="Left" HorizontalAlignment="Left" Margin="292,250,0,0" VerticalAlignment="Top" />
        <TextBox HorizontalAlignment="Left" Height="23" Margin="349,252,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" />
    </Grid>
</Window>

【问题讨论】:

  • 您可以使用像 Snoop 这样的工具在运行时检查您的绑定,看看它们为什么不工作。我没有看到您在任何地方设置 DataContext 的证据。
  • 我也进行了此编辑,但我的绑定仍然无法正常工作

标签: c# mvvm combobox


【解决方案1】:

您的代码存在一些问题。

首先修复 ViewModel 中的属性 Resolution 以防止 StackOverflowException。在 get 和 set 中使用您的字段 _resolution。

    private ObservableCollection < ConfigurationModel > Resolution {
        get {
            return _resolution;
        }
        set {
            _resolution = value;
        }
    }

您的模型中存在类似问题。在这里您可以使用自动属性

    private ObservableCollection<ConfigurationModel> Resolution
    {
        get;
        set;
    }

也许您还应该通过 List 交换 ObservableCollection。但这不是必需的。 _resolution 字段可以移除,Resolution 属性的类型更改为 ObservableCollection

    private ObservableCollection<string> Resolution
    {
        get;
        set;
    }

然后您的构造函数可以更改为

    public ConfigurationModel()
    {
        Resolution = new ObservableCollection<string>() {
            "360 * 720",
            "720 * 1080",
            "1080 * 2060"
        };
    }

还缺少从模型到视图模型的链接。类似的东西:

    private readonly ConfigurationModel _model;

    public ConfigurationViewModel()
    {
        _model = new ConfigurationModel();
    }

然后你必须使用它,所以你必须改变你的财产

    public ObservableCollection<string> Resolution
    {
        get
        {
            return _model.Resolution;
        }
        set
        {
            _model.Resolution = value;
        }
    }

因此,您必须将模型中的修饰符从私有更改为公共。

    public ObservableCollection<string> Resolution
    {
        get;
        set;
    }

现在您可以从 ViewModel 中删除字段 _resolution。

DisplayMemberPath 必须从视图中删除。而且你必须正确设置DataContext。

<Window.DataContext>
    <ViewModels:ConfigurationViewModel />
</Window.DataContext>

到目前为止,您已经得到了结果:

View 中的 SelectedItem 必须绑定到 ViewModel 中的另一个属性。

public string SelectedResolution { get; set; }

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

这应该是进一步发展的良好起点。您可以将 ObservableCollection 中的字符串更改为具有更多属性的自己的类型。然后你需要重新设置DisplayMemberPath。

这是最终代码。

型号:

using System.Collections.ObjectModel;

namespace screensaver.Models
{
    class ConfigurationModel
    {
        public ObservableCollection<string> Resolution
        {
            get;
            set;
        }

        public ConfigurationModel()
        {
            Resolution = new ObservableCollection<string>() {
                "360 * 720",
                "720 * 1080",
                "1080 * 2060"
            };
        }
    }
}

视图模型:

using screensaver.Models;
using System.Collections.ObjectModel;

namespace screensaver.ViewModels
{
    class ConfigurationViewModel
    {
        private readonly ConfigurationModel _model;

        public ConfigurationViewModel()
        {
            _model = new ConfigurationModel();
        }

        public ObservableCollection<string> Resolution
        {
            get { return _model.Resolution; }
            set { _model.Resolution = value; }
        }

        public string SelectedResolution { get; set; }

    }
}

查看:

<Window x:Class="screensaver.Views.ConfigurationWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:ViewModels="clr-namespace:screensaver.ViewModels" Title="ConfigurationWindow"
Height="1000" Width="500">
<Window.DataContext>
    <ViewModels:ConfigurationViewModel />
</Window.DataContext>
<Grid>
    <Label Content="Display" HorizontalAlignment="Left" Margin="7,12,0,0" VerticalAlignment="Top" />
    <ComboBox HorizontalAlignment="Left" Margin="322,14,0,0" VerticalAlignment="Top" Width="120" />
    <ComboBox ItemsSource="{Binding Resolution}" SelectedItem="{Binding SelectedResolution, Mode=TwoWay}" HorizontalAlignment="Left" Margin="74,13,0,0" VerticalAlignment="Top" Width="120" />
    <Label Content="Resolution" HorizontalAlignment="Left" Margin="250,13,0,0" VerticalAlignment="Top" />
    <Button Content="Save" HorizontalAlignment="Left" Margin="80,362,0,0" VerticalAlignment="Top" Width="75" />
    <Button Content="Close" HorizontalAlignment="Left" Margin="350,360,0,0" VerticalAlignment="Top" Width="75" />
    <Label Content="Height" HorizontalAlignment="Left" Margin="72,178,0,0" VerticalAlignment="Top" />
    <TextBox HorizontalAlignment="Left" Height="23" Margin="140,181,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" />
    <Label Content="Width" HorizontalAlignment="Left" Margin="290,175,0,0" VerticalAlignment="Top" />
    <TextBox HorizontalAlignment="Left" Height="23" Margin="346,179,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" />
    <Label Content="Top" HorizontalAlignment="Left" Margin="76,253,0,0" VerticalAlignment="Top" />
    <TextBox HorizontalAlignment="Left" Height="23" Margin="140,255,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" />
    <Label Content="Left" HorizontalAlignment="Left" Margin="292,250,0,0" VerticalAlignment="Top" />
    <TextBox HorizontalAlignment="Left" Height="23" Margin="349,252,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" />
</Grid>
</Window>

【讨论】:

    猜你喜欢
    • 2015-09-15
    • 2021-10-11
    • 2015-07-11
    • 2015-04-27
    • 2013-06-20
    • 2011-06-13
    • 2023-03-18
    • 2018-06-12
    • 2015-08-20
    相关资源
    最近更新 更多