Wpf MVVM中的数据绑定

时间:2017-03-27 12:34:10

标签: wpf mvvm observablecollection

我是WPF和MVVM的新手。

我尝试将数据从mysql数据库提取到ObservableCollection,然后将其绑定到UI。

问题是,我在模型层的第一个ObservableCollection中有数据,但是当我无法将数据发送到ViewModel层时,没有任何内容可以绑定到UI。

class Databasecon 
{
    int i = 0;

    // First Binding for the Database
    public ObservableCollection<Operator> operators { get; private set; }

    public Databasecon()
    {
        this.operators = new ObservableCollection<Operator>(); 
    }

    public void Datacon(string conn)
    {
        MySqlConnection con = null;
        MySqlCommand com = null;
        MySqlDataReader myreader = null;
        int columnOrdinaloperatorname = -1;

        con = new MySqlConnection(conn);
        try
        {
            if (com == null)
            {
                com = new MySqlCommand("SELECT operator_name FROM operators", con);
                com.Connection.Open();

                myreader = com.ExecuteReader();
                columnOrdinaloperatorname = myreader.GetOrdinal("operator_name");

                while (myreader.Read())
                {
                    this.operators.Add(new Operator() { operatorname = myreader.GetString(columnOrdinaloperatorname).ToString() });

                    i++;
                }  
            }

            MessageBox.Show(operators.Count.ToString());
        }
        catch (MySqlException ex)
        {
            MessageBox.Show(ex.ToString());
        }
        finally
        {
            if (myreader != null)
                myreader.Close();

            if (com != null)
            {
                if (com.Connection != null)
                    com.Connection.Close();
            }
        }
    }
}

class Operator
{
    public string operatorname { get ; set; }
}

class collect : INotifyPropertyChanged
{
    private Databasecon databasecon = null;

    public event PropertyChangedEventHandler PropertyChanged;

    public ObservableCollection<Operator> operators
    {
        get
        {
            if (this.databasecon.operators != null)
            {
                return this.databasecon.operators;                   
            }
            else
            {
                return null;
            }
        }
        set
        {
            this.operators = value; RaisePropertyChanged("operators");
        }
    }

    private void RaisePropertyChanged(string propertyName)
    {
        var handler = this.PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public collect()
    { 
        this.databasecon = new Databasecon();
    }
}

Xaml代码是:

 <Window.DataContext>
    <vm:collect/>
</Window.DataContext>
<Grid>
    <TextBlock Margin="459,51,-459,-51"><InlineUIContainer>
                <TextBlock x:Name="textBlock" TextWrapping="Wrap" Text="{Binding Path=operators}"  Width="198" FontSize="28" Height="66"/>
            </InlineUIContainer></TextBlock>
    <ListBox x:Name="listBox"  HorizontalAlignment="Left" Height="102" Margin="115,240,0,0" VerticalAlignment="Top" Width="339" ItemsSource="{Binding operators}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <TextBlock >
                        <Run Text="{Binding operatorname}"></Run>
                    </TextBlock>
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

任何人都可以帮我吗?

1 个答案:

答案 0 :(得分:0)

你的绑定对我来说似乎很好 - 这就是我测试它们所做的:

<Window.DataContext>
    <vm:collect/>
</Window.DataContext>
<Grid>
    <Button VerticalAlignment="Top" HorizontalAlignment="Left" Command="{Binding AddThings}" Height="25" Width="Auto">Add Stuff</Button>
    <TextBlock Margin="459,51,-459,-51"><InlineUIContainer>
            <TextBlock x:Name="textBlock" TextWrapping="Wrap" Text="{Binding Path=operators}"  Width="198" FontSize="28" Height="66"/>
        </InlineUIContainer></TextBlock>
    <ListBox x:Name="listBox"  HorizontalAlignment="Left" Height="102" Margin="115,240,0,0" VerticalAlignment="Top" Width="339" ItemsSource="{Binding operators}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <TextBlock >
                    <Run Text="{Binding operatorname}"></Run>
                    </TextBlock>
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Grid>

C#:

class Databasecon
{
    int i = 0;

    // First Binding for the Database
    public ObservableCollection<Operator> operators { get; private set; }

    public Databasecon()
    {
        this.operators = new ObservableCollection<Operator>();
    }

    public void Datacon()
    {
            this.operators.Add(new Operator() { operatorname = "Hello world!"});
    }
}

class Operator
{
    public string operatorname { get; set; }
}

class collect : INotifyPropertyChanged
{
    private Databasecon databasecon = null;

    public event PropertyChangedEventHandler PropertyChanged;

    public ICommand AddThings { get; set; }

    public ObservableCollection<Operator> operators
    {
        get
        {
            if (this.databasecon.operators != null)
            {
                return this.databasecon.operators;
            }
            else
            {
                return null;
            }
        }
        set
        {
            this.operators = value; RaisePropertyChanged("operators");
        }
    }

    private void RaisePropertyChanged(string propertyName)
    {
        var handler = this.PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public collect()
    {
        this.databasecon = new Databasecon();
        AddThings = new SimpleCommand(() => databasecon.Datacon()); 
    }
}

public class SimpleCommand : ICommand
{
    private Action _command; 

    public SimpleCommand(Action command)
    {
        _command = command; 
    }

    public bool CanExecute(object parameter)
    {
        return true; 
    }

    public event EventHandler CanExecuteChanged;

    public void Execute(object parameter)
    {
        if (_command != null)
            _command();
    }
}

您的问题可能在于设置数据上下文的方式。目前,您的窗口每次实例化时都会创建视图模型的新实例,但由于您没有设置名称,我认为此实例仅由窗口使用。您可以将vm设为公共属性,并调用窗口保存的实例来填充集合:

<Window.DataContext>
    <vm:collect x:Name="Collect"/>
</Window.DataContext>


window.Collect.Datacon("[My connection string]");

或者将您要使用的实例传递给视图模型构造函数并将其设置在那里:

 public MainWindow(object viewModel)
    {
        DataContext = viewModel; 
        InitializeComponent();
    }