问题
Update Now I think I have narrowed the problem. I created single class
public class OptionStrike
{
public OptionStrike(double p1, double p2, int p3)
{
// TODO: Complete member initialization
P_OI = p1;
StrikePrice = p2;
P_Volume = p3;
}
public OptionStrike()
{
// TODO: Complete member initialization
}
public double P_OI { get; set; }
public double P_Volume { get; set; }
public double StrikePrice { get; set; }
}
Now, if i load the values to this OptionStrike as
private void Test(object obj)
{
oOs = new ObservableCollection<OptionStrike>(new OptionStrike[]
{
new OptionStrike(4201, 7500.00, 12345),
new OptionStrike(818859, 7500.00, 123),
new OptionStrike(84545, 8000.00, 23645),
new OptionStrike(8889955, 8000.00,99999)
});
}
it shows in the datagrid in the window, but if I do it like this:
_oOC = new ObservableCollection<OptionStrike>();
OptionStrike os = new OptionStrike();
os.StrikePrice=7500;
os.P_Volume=545;
os.P_OI=45454;
_oOC.Add(os);
os.StrikePrice = 7600;
os.P_Volume = 5566;
os.P_OI = 45455;
_oOC.Add(os);
The datagrid is blank..
The field oOC is populating allright, and I have checked it, but it is still not showing in the Datagrid... Any suggestions...
oOC is declared as
private ObservableCollection<OptionStrike> _oOC;
public ObservableCollection<OptionStrike> oOC
{
get { return _oOC; }
set
{
if (value != _oOC)
{
_oOC = value;
OnPropertyChanged(new PropertyChangedEventArgs("oOC"));
}
}
}
Old Question I have an ObservableCollection which I am trying to bind to a DataGrid..
private ObservableCollection<Option> _optionChain = new ObservableCollection<Option>();
public ObservableCollection<Option> OptionChain
{
get { return _optionChain; }
set
{
if (value != _optionChain)
{
_optionChain = value;
PropChanged("OptionChain");
}
}
}
My OptionChain collection is being populated like
private void ProcessOptionsData()
{
OptionChain = d.ProcessOptionChainData(OptionChainHtmlElement, Ticker, Expiry);
}
Option Class has
public string type; // option typ (put/call)
public string stock; // option stock ticker
public string symbol; // option symbol
public double strike; // option strike price
And XAML is
<DataGrid ItemsSource="{Binding OptionChain}" AutoGenerateColumns="False" DataContext="{Binding Mode=Default}">
<DataGrid.Columns>
<DataGridTextColumn Header="Type" Binding="{Binding type}" />
<DataGridTextColumn Header="Strike" Binding="{Binding strike}" />
</DataGrid.Columns>
</DataGrid>
Now the Datagrid is not being populated. I tried AutoGenerateColumn="True"
, but to no avail... also tried DataGridTextColumn Binding to Option.strike
and so on, but was unsuccessful..
Where am I going wrong?
(I am using ViewModelLocator)
Edit
Now i have cleared everything.. Just have one textbox, and one label. When i write something in textbox, it is not being reflected in label.. code is as
public class MainViewModel : INotifyPropertyChanged
{
#region Fields
private string _ticker;
public string Ticker
{
get { return _ticker; }
set
{
if (value != _ticker)
{
_ticker = value;
OnPropertyChanged("Ticker");
}
}
}
private string _status;
public string Status
{
get { return _status;}
set
{
if (value!=_status)
{
_status = value;
OnPropertyChanged("Status");
}
}
}
public string PostBack
{
get { return string.Format("{0}, for expiry at ", Ticker); }
}
#endregion Fields
public event PropertyChangedEventHandler PropertyChanged;
// Create the OnPropertyChanged method to raise the event
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
` MainWindow's XAML is like
<Grid>
<StackPanel Orientation="Horizontal">
<TextBox Background="Transparent" Foreground="White" Text="{Binding Ticker}" HorizontalContentAlignment="Left" Width="150" VerticalContentAlignment="Center" Height="28" FontSize="18" Margin="10,0,0,0" />
<Label Content="{Binding PostBack}" Width="250" Height="28" Margin="10,0,0,0" />
</StackPanel>
</Grid>
Codebehind of MainWindow is being used for datacontext..
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
MainViewModel mvm = new MainViewModel();
this.DataContext = mvm;
}
}
回答1:
With the new code provided, it looks like you'd just need to add a PropertyChanged notification for the PostBack
property.
Since that property is calculated, it won't be recalculated automatically unless you notify it's changed. And you should do so in the Ticker
setter because PostBack depends on its value. Like this:
private string _ticker;
public string Ticker
{
get { return _ticker; }
set
{
if (value != _ticker)
{
_ticker = value;
OnPropertyChanged("Ticker");
OnPropertyChanged("PostBack");
}
}
}
That way, every time you type something on your TextBox, you'll notify the view that PostBack's value has changed too, and that it has to refresh the Label's Binding.
Oh, by the way, TextBox's default Bindings have UpdateSourceTrigger
set to LostFocus
, I think. If you want the Label to be updated every time you write something without having to wait for leaving the TextBox, you might want to set it to PropertyChanged
(and even use a Delay
for better performance):
<TextBox Background="Transparent"
Foreground="White"
Text="{Binding Ticker, UpdateSourceTrigger=PropertyChanged, Delay=1000}"
HorizontalContentAlignment="Left"
Width="150"
VerticalContentAlignment="Center"
Height="28"
FontSize="18"
Margin="10,0,0,0" />
回答2:
One problem is that you don't have getters or setters on your Option class properties.
It should look like this:
public string type { get; set; }
public string stock { get; set; }
public string symbol { get; set; }
public double strike { get; set; }
As you had it, it would cause binding exceptions as the properties would not be found.
Also your DataContext in the XAML maybe wrong - but this is not possible to check with the code you have given.
回答3:
NotifyPropertyChanged does not work the same way with a collection
try
private void ProcessOptionsData()
{
OptionChain.Clear();
ForEach(Option opt in d.ProcessOptionChainData(OptionChainHtmlElement, Ticker, Expiry);
OptionChain.Add(opt);
}
来源:https://stackoverflow.com/questions/30786678/databinding-observablecollectiont-to-datagrid-not-working