I am a C++ developer and i recently shifted to C# WPF. I am working on a WPF App where I am supposed to dynamically generate button, label, textbox and togglebutton. I have done the following:
XAMl:
<ListBox x:Name="myViewChannelList" HorizontalAlignment="Stretch" Height="Auto" ItemsSource="{Binding VoltageCollection}" Margin="0" VerticalAlignment="Stretch" Width="Auto">
<ListBox.ItemTemplate>
<DataTemplate >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="170" />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Content="{Binding ChannelName}" Margin="50,20,0,0"></Label>
<Grid Grid.Column="1">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0" Text="{Binding VoltageText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Height="25" Width="50" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="170,20,0,0" />
<Button Grid.Column="1" Content="Set" Height="25" CommandParameter="{Binding VoltageText}" Command="{Binding VoltageCommand}" Width="50" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="20,20,0,0" ></Button>
</Grid>
<Label Grid.Column="2" Content="{Binding Path=Voltage}" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="210,20,0,0" ></Label>
<ToggleButton Grid.Column="3" Content="On" Height="25" Width="30" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="120,20,0,0" ></ToggleButton>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button Content="Redhook" Command="{Binding RedhookCommand}" FontSize="13" Height="25" HorizontalAlignment="Center" Margin="0,0,0,0" Name="Refresh1Btn" VerticalAlignment="Center" Width="105" />
ViewModel Class:
class ChannelList : INotifyPropertyChanged
{
private ICommand m_voltageCommand;
public ChannelList()
{
m_voltageCommand = new DelegateVoltageCommand(x => SetCommandExecute(x));
}
public void Initialize()
{
VoltageCollection = new ObservableCollection<VoltageModel> { new VoltageModel() { ChannelName = "VDD__Main", VoltageText = String.Empty, VoltageCommand = m_voltageCommand },
new VoltageModel() { ChannelName = "VDD__IO__AUD", VoltageText = String.Empty, VoltageCommand = m_voltageCommand },
new VoltageModel() { ChannelName = "VDD__CODEC__AUD", VoltageText = String.Empty, VoltageCommand = m_voltageCommand }
};
}
public ObservableCollection<VoltageModel> VoltageCollection { get; set; }
/// <summary>
/// Event On Get Current Frquency Button Click
/// </summary>
private ICommand mRedhookCommand;
public ICommand RedhookCommand
{
get
{
if (mRedhookCommand == null)
mRedhookCommand = new DelegateCommand(new Action(GetCurrentFreqExecuted), new Func<bool>(GetCurrentFreqCanExecute));
return mRedhookCommand;
}
set
{
mRedhookCommand = value;
}
}
public bool GetCurrentFreqCanExecute()
{
return true;
}
public void GetCurrentFreqExecuted()
{
VoltageCollection.Clear();
VoltageCollection = new ObservableCollection<VoltageModel> { new VoltageModel() { ChannelName = "VDD__Main", VoltageText = String.Empty, VoltageCommand = m_voltageCommand },
new VoltageModel() { ChannelName = "VDD__IO__AUD", VoltageText = String.Empty, VoltageCommand = m_voltageCommand },
new VoltageModel() { ChannelName = "VDD__CODEC__AUD", VoltageText = String.Empty, VoltageCommand = m_voltageCommand },
new VoltageModel() { ChannelName = "VDD__LDO", VoltageText = String.Empty, VoltageCommand = m_voltageCommand},
new VoltageModel() { ChannelName = "VDD__AMP", VoltageText = String.Empty, VoltageCommand = m_voltageCommand}
};
}
Thus on application startup I am able to display the dynamically generated controls. But on clicking REDHOOK button, i want to update the list with new values as mentioned in my GetCurrentFreqExecuted(). When I am trying to do this, the list gets cleared but doesnt update the new values. How can i achieve this???
The problem is, Your VoltageCollection does not notify when it’s instance is changed.
So what you need to do is call PropertyChanged when assigning instance to the VoltageCollection.
Other way,
In your
GetCurrentFreqExecuted()method, do not assign an instance to the VoltageCollection. ie, RemoveVoltageCollection=new ObservableCollection<>....().And add Each item using for each loop.
Now your code looks like