WPF MVVM Combobox绑定

时间:2017-07-31 17:23:23

标签: c# mvvm combobox

我已经在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
                }
            };
        }
    }
}

这是我的ViewModel

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>

1 个答案:

答案 0 :(得分:1)

您的代码存在一些问题。

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

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

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

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

也许您还应该通过List&lt;&gt;交换ObservableCollection。但这不是必要的。可以删除字段_分辨率,并将分辨率属性的类型更改为ObservableCollection&lt; string&gt;。

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

然后可以将构造函数更改为

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

还缺少从Model到ViewModel的链接。这样的事情:

    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。

必须从View中删除DisplayMemberPath。你必须正确设置DataContext。

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

到目前为止,你有这样的结果:

enter image description here

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>