Wpf MVVM中的数据绑定
问题描述:
我是WPF和MVVM中的新成员。Wpf MVVM中的数据绑定
我尝试从mysql数据库获取数据到ObservableCollection
然后将其绑定到UI。
问题是,我在Model层的第一个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>
谁能帮助我?
答
你绑定似乎没什么问题 - 这里就是我所做的测试他们:
<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();
}
}
您的问题可能在于你设置你的数据上下文的方式。目前,您的窗口在每次实例化时都会创建视图模型的新实例,但由于您没有设置名称,因此我认为此实例仅供窗口使用。你可以把虚拟机的公共属性和调用窗口保持填充集合实例:
<Window.DataContext>
<vm:collect x:Name="Collect"/>
</Window.DataContext>
window.Collect.Datacon("[My connection string]");
或者通过你打算使用的视图模型构造,并设置有实例:
public MainWindow(object viewModel)
{
DataContext = viewModel;
InitializeComponent();
}
感谢您的答案。您向我解释我如何使用ICommand接口在UI中进行绑定,而不是使用按钮 – Ahmad
我不太确定您的意思。你的意思是你想在UI加载时填充你的列表? 在这种情况下,您只需在collect构造函数中添加对databasecon.Datacon(“[connection string]”)的调用即可。 – Jonny
感谢您的帮助它现在的工作 http://stackoverflow.com/questions/18593720/window-load-event-in-mvvm 这就是我需要的 – Ahmad