UWP update a itemscontrol with an array that keeps updating - c#

I have an array that keeps changing its values, because of this I want to have the apps UI refreshing every time the array's values do. I have this bound with an itemsControl. I can show the first array's values but then I can't update them I have tried .items.Clear() but its not working. Here are snippets of the .xaml and the xaml.cs. I actually took the code of the .xaml from a question from this site.
.xaml
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBox Text="Testing" IsReadOnly="True"></TextBox>
<ItemsControl x:Name="itemsControl"
ItemsSource="{Binding itemsControl}"
FontSize="24">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Width="Auto"
Margin="0 12"
HorizontalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackPanel Grid.Column="0"
Grid.Row="0"
Orientation="Horizontal">
<TextBlock Name="txtblk0" Text="{Binding}" />
</StackPanel>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
.xaml.cs
String c = (new String(cArray));
string[] arr = null;
string[] data = null;
if (c != null)
{
arr = c.Split('\n');
if (arr.Length > 0)
{
data = arr[0].Split(',');
}
}
for(int index = 0; index < 4; index++)
{
itemsControl.Items.Add(float.Parse(data[index]));
}
itemsControl.Clear();
If anyone has an idea of how I can do this I will be very grateful, thanks in advance and I will try to answer any questions as soon as possible!

What you're missing is an understanding of how bindings are triggered to update.
The INotifyPropertyChanged interface contains a method (PropertyChanged) and when called and passed the name of a property will tell the binding system that the property has changed and the binding should be updated.
INotifyCollectionChanged is the equivalent for collections, and communicates when a collection has changed. i.e. something added, removed, or the list cleared.
ObservableCollection<T> contains an implementation of INotifyCollectionChanged that makes it easy to work with lists, collections, etc. that change.
If you used an ObservableCollection<float> instead of an array you'd be able to modify the list and have the UI updated to reflect this easily.
As a starter, see the following which demonstrates how easy it is to use an ObservableCollection.
XAML:
<StackPanel>
<Button Click="Button_Click">add an item</Button>
<ItemsControl ItemsSource="{Binding Items}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
code behind;
public MainPage()
{
this.InitializeComponent();
// Initialize the property
this.Items = new ObservableCollection<string>();
// Use self as datacontext (but would normally use a separate viewmodel)
this.DataContext = this;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
// add a new item to the UI
this.Items.Add(DateTime.Now.ToString());
}
// The "collection" that is shown in the UI
public ObservableCollection<string> Items { get; set; }

Related

C# WPF - variable value won't display on Textboxes (DataContext?)

I got a really tricky and annoying problem with my C# WPF Application. I guess it's not a big deal for a good programmer to solve it, but I don't know how to fix it yet. For school, I have to program an application which depicts a process. So I get Data by an XML-File, have to calculate some values, display them for User Interaction etc. and at the end the output is again a file, which can be processed further.
For that, I got different UserControls, which depicts different modules for example, one for the Data Import, the other one for calculating and displayng values and so on. The Main Window is like the free space or the place-maker on which the different modules are loaded depending on where we are in the process.
My problem now is that the values I calculate in my UserControl won't display in my UI respectively my application and I don't really know why. 0 is the only value which is transferred to the application. Curious about it, is that in the Debugger the values are correct, but in the display itself there is only a 0.
Ok, so I show you now the code of the different files (I'm not the best programmer, so maybe the code is sometimes a bit dirty).
I got a Main UserControl, let's call it UC_Main, and in this UserControl you can switch between 3 different other UserControls depending on which Radiobutton in the UC_Main is checked. (The UC_Main is always displayed, because in this there are only the 3 radio buttons and underneath is a big free space, where the different UserControls 1, 2 and 3 are loaded).
UC_Main.xaml
<UserControl.Resources>
<DataTemplate x:Name="UC1_Template" DataType="{x:Type local:UC1}">
<local:UC1 DataContext="{Binding}" />
</DataTemplate>
<DataTemplate x:Name="UC2_Template" DataType="{x:Type local:UC2}">
<local:UC2 DataContext="{Binding}" />
</DataTemplate>
<DataTemplate x:Name="UC3_Template" DataType="{x:Type local:UC3}">
<local:UC3 DataContext="{Binding}" />
</DataTemplate>
</UserControl.Resources>
<Border Padding="10">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<!-- In the First Row there are the radio buttons in the second the
different UserControls 1, 2 or 3 -->
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<materialDesign:ColorZone Mode="PrimaryMid" Width="400" HorizontalAlignment="Left">
<StackPanel Grid.Row="0" Orientation="Horizontal" Margin="2">
<RadioButton x:Name="UC1_radiobutton" Checked="UC1_radiobutton_Checked"
Style="{StaticResource MaterialDesignTabRadioButton}"
Margin="4"
IsChecked="True"
Content="UserControl1" />
<RadioButton x:Name="UC2_radiobutton" Checked="UC2_radiobutton_Checked"
Style="{StaticResource MaterialDesignTabRadioButton}"
Margin="4"
IsChecked="False"
Content="UserControl2" />
<RadioButton x:Name="UC3_radiobutton" Checked="UC3_radiobutton_Checked"
Style="{StaticResource MaterialDesignTabRadioButton}"
Margin="4"
IsChecked="False"
Content="UserControl3" />
</StackPanel>
</materialDesign:ColorZone>
<ContentControl Grid.Row="1" Content="{Binding}" />
</Grid>
</Border>
</UserControl>
UC_Main.xaml.cs
public partial class UC_Main : UserControl
{
public UC_Main()
{
InitializeComponent();
}
private void UC1_radiobutton_Checked(object sender, RoutedEventArgs e)
{
DataContext = new UC1();
}
private void UC2_radiobutton_Checked(object sender, RoutedEventArgs e)
{
DataContext = new UC2();
}
private void UC3_radiobutton_Checked(object sender, RoutedEventArgs e)
{
DataContext = new UC3();
}
}
}
To keep it simple, I'll only show you the Code of UserControl 1, because UC 2 and 3 are pretty the same beside other variables or values.
UC1.xaml
<Border Padding="10">
<StackPanel>
<!-- To keep the example simple, I got 1 Row and 2 Colums; in each
is one TextBox -->
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="2*" />
</Grid.ColumnDefinitions>
<TextBox x:Name="TextBox1" Grid.Column="0" IsTabStop="False"
Text="{Binding Path=variable1, Mode=TwoWay}"
VerticalAlignment="Center"
HorizontalAlignment="Center"
TextAlignment="Center"
Height="25"
Width="85"
Foreground="DarkGray"
IsReadOnly="True" />
<TextBox x:Name="TextBox2" Grid.Column="1" IsTabStop="False"
Text="{Binding Path=variable2, Mode=TwoWay}"
VerticalAlignment="Center"
HorizontalAlignment="Center"
TextAlignment="Center"
Height="25"
Width="85"
Foreground="DarkGray"
IsReadOnly="True" />
</Grid>
</StackPanel>
</Border>
</UserControl>
UC_1.xaml.cs
public partial class UC1 : UserControl
{
public MainWindow Speaker;
public ValueStore vs;
public UC1()
{
InitializeComponent();
Speaker = MainWindow.AppWindow;
vs = new ValueStore();
DataContext = vs;
}
public void calc_data()
{
// I get the data from the data import (XML-File), which is saved in
// a dictionary (strings), converting them to int (so I can do some
// math operations) and save them in my variable.
// UC_Other is a UserControl, where the data import happens
// dict_other is the dictionary, where the data from the import is
// saved
vs.variable1 =
Convert.ToInt32(MainWindow.AppWindow.UC_other.dict_other["0"].Amount);
vs.variable2 =
Convert.ToInt32(MainWindow.AppWindow.UC_other.dict_other["1"].Amount);
}
I call the function calc_data() in an UserControl before, so the data gets calculated and saved in my variables before my UserControl shows up. I declare a new public instance of my UC1 and call the function via UC1.calc_data(); (which is linked to a Button, that is loading my UC_Main).
ValueStore.cs
public class ValueStore : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
if(PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
private int _variable1;
public int variable1
{
get { return _variable1; }
set { _variable1 = value; OnPropertyChanged("variable1"); }
}
private int _variable2;
public int variable2
{
get { return _variable2; }
set { _variable2 = value; OnPropertyChanged("variable2"); }
}
When I look in the debugger after the method calc_data() is called, the values are correct saved in my ValueStore instance and the TextBoxes are showing me in the Debugger that the correct value is in there (the Debugger says "Name: TextBox1" and "Value: {System.Windows.Controls.TextBox: 100}"; 100 is the value I got from the dictionary), but in my application itself there is only the value 0 displayed.
What I don't really understand is, when I change the type from variable1 to string in my ValueStore.cs and save it in my variable in the method calc_data()(without Convert.ToInt32), it doesn't even show a 0 any more in my application, but in the debugger there is still the value "100".
There are a few things here, but my best guess why your debugging-values are correct while none are updated to the GUI is here:
public partial class UC_Main : UserControl
{
public UC_Main()
{
InitializeComponent();
}
private void UC1_radiobutton_Checked(object sender, RoutedEventArgs e)
{
DataContext = new UC1();
}
private void UC2_radiobutton_Checked(object sender, RoutedEventArgs e)
{
DataContext = new UC2();
}
private void UC3_radiobutton_Checked(object sender, RoutedEventArgs e)
{
DataContext = new UC3();
}
}
You are creating new instances of these classes of the code-behind to the usercontrols. But the usercontrol objects are already created by the UC_Main.xaml so during runtime, you have two objects for example of the UC1 class, one which is your bound to your GUI and one where you store and update your values. The one you see on your GUI doesn't get any values updates, which is why you aren't seeing anything.
I currently can't test the code myself, but from what I can see that is where the issue lies.
Furthermore it is a bit confusing to me, why you are using databinding for code-behind.
(You are using the code-behind of the UC-classes as datacontext for the main class, which is....weird ;) I think in your case no databinding whatsoever is really needed, however if you want to do stuff with databinding you should probably read up on MVVM)

In wpf Clear ListBox items at Runtime

I am using wpf listbox, i cannot able to clear the list when am calling the reload data function, i just want to reload new data at runtime,while page loading it loads the data correctly, when i refresh the new data is fetched in itemsource i can see that in debug mode, but no new data in listbox, old data remains in the list, i cant even clear, when i call list.items.clear(), i tried lot ways, is there any problem in my XAML binding, the following is my code.
XAML:
<ListBox ItemsSource="{Binding}" HorizontalContentAlignment="Left" x:Name="lstbxindex" Foreground="White" FontSize="20px" Height="400" BorderBrush="#555555" Margin="10,34,16,0" VerticalAlignment="Top" Width="322" Background="#555555" >
<ListBox.ItemTemplate>
<DataTemplate>
<WrapPanel Orientation="Horizontal" Margin="5" >
<StackPanel Orientation="Horizontal">
<TextBlock x:Name="txtblckroundhour" Height="40px" Width="55px" Text="{Binding RoundedHours}" FontSize="14" Background="#555555" Loaded="txtblckroundhour_Loaded" Foreground="White"></TextBlock>
<Label x:Name="items" MouseDoubleClick="items_MouseDoubleClick" Content="{Binding ProjectRow.Name}" Background="#555555" FontSize="20" Loaded="items_Loaded" Visibility="Visible" Margin="35,0,0,0" Width="230" Foreground="White"></Label>
</StackPanel>
<StackPanel Orientation="Vertical">
<ComboBox Height="40px" Width="290" Margin="-230,0,0,0" Loaded="ComboBox_Loaded" Visibility="Hidden" IsEditable="True" FontSize="20" Background="White" Foreground="Black"></ComboBox>
</StackPanel>
<!--<ComboBox x:Name="ComboBox_AddItem" Height="40px" Width="290" Margin="-35,35,0,0" Loaded="ComboBox_AddItem_Loaded" IsEditable="True" FontSize="20" Background="White" Visibility="Hidden" Foreground="Black"></ComboBox>-->
</WrapPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Get the list of values
private List<ProjectInformation> projectInformationList1 = new List<ProjectInformation>();
// Here define the actual binding of the userinterface listbox to the in-memory list of objects.
foreach (DtoProjectsRow row in projectsTable.Rows)
{
projectInformationList1.Add(new ProjectInformation(row));
}
lstbxindex.DataContext = projectInformationList1;
In SO I tried some solution but unfortunately it is not work for me. Last I tried,
XAML.cs page
public static readonly DependencyProperty MyListProperty = DependencyProperty.Register("MyList", typeof(ObservableCollection<String>), typeof(Window));
public ObservableCollection<String> MyList
{
get
{
return (ObservableCollection<String>)GetValue(MyListProperty);
}
set
{
SetValue(MyListProperty, value);
}
}
XAML:
<ListBox ItemsSource="{Binding **ElementName=Window**}" HorizontalContentAlignment="Left" x:Name="lstbxindex" Foreground="White" FontSize="20px" Height="400" BorderBrush="#555555" Margin="10,34,16,0" VerticalAlignment="Top" Width="322" Background="#555555" >
Using this above solution listitems are clear but when pageloading the listboxitems are clear but I don't want to clear the iistboxitems, after updating the values from user it will reload the updated value in listbox.
lstbxindex.ItemsSource = null;
But its not work.For pageload listbox loaded all items,every 15 min interval it will call the load function for firsttime it will reload the updatedvalues but second time it will reload the updated values and previous values remains in listbox again.
I misunderstood initially thinking you were using MVVM, instead you're populating the ListView datasource from code behind.
Your line lstbxindex.DataContext = projectInformationList1; does not set the Data as you'd think. Instead try lstbxindex.DataContext = this; which means you're telling your view to look for the data source in code behind.
As such, I suggest adding using System.ComponentModel; and using BindingList, a comparison is here.
private BindingList<ProjectInformation> projectInformationList1 = new BindingList<ProjectInformation>();
And you just need this once:
foreach (DtoProjectsRow row in projectsTable.Rows)
{
projectInformationList1.Add(new ProjectInformation(row));
}
lstbxindex.DataSource = projectInformationList1;
As mentioned in the comments, if you did not use ItemsSource="{Binding projectInformationList1}" as I suggested in a comment to your question, this is the alternative:
private ObservableCollection<ProjectInformation> projectInformationList1 = new ObservableCollection<ProjectInformation>();
foreach (DtoProjectsRow row in projectsTable.Rows)
{
projectInformationList1.Add(new ProjectInformation(row));
}
lstbxindex.DataContext = projectInformationList1;
You should have a view model class with a collection property, e.g. like this:
public class ViewModel
{
public ObservableCollection<ProjectInformation> Projects { get; }
= new ObservableCollection<ProjectInformation>();
}
Set the DataContext of your Window or Page in XAML like this:
<Window.DataContext>
<local:ViewModel/>
</Window.DataContext>
and bind the ListBox like this:
<ListBox ItemsSource="{Binding Projects}">
...
</ListBox>
To clear all items in the source collection, access the DataContext in code behind:
var vm = (ViewModel)DataContext;
vm.Projects.Clear();
Edit: Instead of assigning the DataContext in XAML, you may as well do it in code behind, even before the Page or Window is initialized:
public MainWindow()
{
DataContext = new ViewModel();
InitializeComponent();
}
Added the line in loadfunction, Initially set null for ItemSource and then set null to the list object
lstbx.ItemsSource=null;
lstbx.Items.Clear();
ProjectInfoList1=null;
it will clear the listboxitems and reload with updated values only.
private BindingList<ProjectInfo> projectInfoList1 = new BindingList<ProjectInfo>();
Public void loadfunction()
{
lstbx.ItemsSource=null;
lstbx.Items.Clear();
ProjectInformationList1=null;
foreach (DtoProRow row in table.Rows)
{
projectInfoList1.Add(new ProjectInfo(row));
}
lstbx.DataContext = projectInfoList1;
}

ListView Keep ListViewHeaderItem On Top

I start by explaining what I want to achieve:
The Letter "A" is one ListViewHeaderItem in my Listview. Without Scrolling the top of the List is looking like this.
After I am Scrolling the ListViewHeaderItem "A" is moving downwards with the rest of the items -
but how can I achieve that the Header is staying on top as Kind of the first item until the Letter "B" with ist subitems is coming? An example of the behaviour I want to achieve is the official "Mail" app for Windows 10 by Microsoft. It is keeping the datetime at the top until emails are coming which have been written one day earlier.
I don't know if this question is already existing but I don't know how it is called and I don't know what to Google for.
According to your description, I think what you want is a grouped ListView. The key points here is using CollectionViewSource as ItemsSource and setting GroupStyle to specify how groups are displayed. Following is a simple sample:
In XAML
<Page.Resources>
<CollectionViewSource x:Name="groupInfoCVS" IsSourceGrouped="True" />
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<ListView ItemsSource="{Binding Source={StaticResource groupInfoCVS}}">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Margin="15" Text="{Binding Path=Text}" />
</DataTemplate>
</ListView.ItemTemplate>
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<Grid Background="LightGray">
<TextBlock Margin="10" Foreground="Black" Text="{Binding Key}" />
</Grid>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListView.GroupStyle>
</ListView>
</Grid>
And in code-behind
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
List<TestDemo> list = new List<TestDemo>();
for (int i = 0; i < 6; i++)
{
list.Add(new TestDemo { Key = "A", Text = $"Test A {i}" });
list.Add(new TestDemo { Key = "B", Text = $"Test B {i}" });
}
var result = from t in list group t by t.Key;
groupInfoCVS.Source = result;
}
}
public class TestDemo
{
public string Key { get; set; }
public string Text { get; set; }
}
And it looks like:
For more info, please see How to group items in a list or grid (XAML) and Simple ListView Sample in ListView and GridView sample on GitHub.

binding data - inotifypropertychanged does not work

I have a listBox1 in which data are binding from the list. Then I want to when I select any item from listBox1 in listBox2 will binding data from another list.
private void listBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
Teams teams = (Teams)listBox1.SelectedItems[0];
getH2hResults("//td[#class='hell']", teams.Team1, teams.Team2); // add elements to list
getH2hResults("//td[#class='dunkel']", teams.Team1, teams.Team2); // and here also
listBox2.ItemsSource = lists.h2hList;
}
On the first time this work, but for the twice time listBox2 doesn't displays new data.
public class Lists : BindableBase
{
public Lists()
{
_teamsList = new List<Teams>();
_h2hList = new List<H2H>();
}
private List<Teams> _teamsList;
public List<Teams> teamsList
{
get
{
return _teamsList;
}
set
{
if (value != _teamsList)
{
_teamsList = value;
RaisePropertyChanged("teamsList");
}
}
}
private List<H2H> _h2hList;
public List<H2H> h2hList
{
get
{
return _h2hList;
}
set
{
if (value != _h2hList)
{
_h2hList = value;
RaisePropertyChanged("h2hList");
}
}
}
}
And XAML
<ListBox Name="listBox1" Width="300" Height="300"
VerticalAlignment="Top"
HorizontalAlignment="Left"
ItemsSource="{Binding teamsList}" SelectionChanged="listBox1_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Foreground="#FF4273CD" Text="{Binding Team1, Mode=TwoWay}"></TextBlock>
<TextBlock Text=" vs " FontWeight="Bold"></TextBlock>
<TextBlock Foreground="#FF4273CD" Text="{Binding Team2, Mode=TwoWay}"></TextBlock>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<ListBox Name="listBox2" Grid.Column="1" Width="300" Height="300"
VerticalAlignment="Top"
HorizontalAlignment="Left"
ItemsSource="{Binding h2hList}" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding date, Mode=TwoWay}"></TextBlock>
<TextBlock Text="{Binding result, Mode=TwoWay}"></TextBlock>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
RaisePropertyChanged("teamList");
is Wrong your propery is named 'teamsList' with an S,
change to:
RaisePropertyChanged("teamsList");
It is the public property you bind to and notify changes of,
edit:
also change your binding:
ItemsSource="{Binding teamList}"
to
ItemsSource="{Binding teamsList}"
Edit 2:
listBox2.DataContext = xxx
Not itemsource = xxx
With the line (in listBox1_SelectionChanged)
listBox2.ItemsSource = lists.h2hList;
you are effectively removing the binding from the ItemsSource property of listBox2.
Instead, you should only update the h2hList property in your Lists class (which presumably happens in getH2hResults) and remove the above line from your code.
Note however that it is not sufficient to clear and re-fill that list. You need to set the h2hList property in order to get a property change notification raised:
var newList = new List<H2H>();
// fill newList before assigning to h2hList property
lists.h2hList = newList;
If you want to keep the list and just change its elements, you would need to use ObservableCollection<H2H> instead of List<H2H> as collection type. This would be the better approach anyway, as you would not have to care for when exactly you add elements to a newly created collection.

Can I swap a buttons content databind to a different databind in code?

I cannot find any examples to make me understand how and if I can change the databind in c# at the click of a button on, in my case a toggleswitch, Basically I have 32 buttons in my app and those 32 buttons act the same but need different text with-in them depending on some toggle switches they are currently databinded so the text can be saved and retrieved from local storage but what values it gets depends on the state of these toggle switches.
So I currently have :
<Button x:Name="_ovButton1" Content="{Binding Source={StaticResource AppSettings}, Path=ovName1_1Value, Mode=TwoWay}" Margin="2,0,250,0" VerticalAlignment="Top" FontSize="14" Height="72" FontWeight="Bold" MouseLeftButtonUp="_ovButton1_MouseLeftButtonUp" MouseLeftButtonDown="_ovButton1_MouseLeftButtonDown" ClickMode="Hover" Hold="_ovButton1_Hold"/>
and I want when a user changes the state of a toggleswitch to change the
{StaticResource AppSettings}, Path=ovName1_1Value, Mode=TwoWay}
to for example:
{StaticResource AppSettings}, Path=ovName1_2Value, Mode=TwoWay}
but I cannot find any example that shows how to do that in c#
what code do I need to do that?
You can specify the target of databinding in code like this:
MyData myDataObject = new MyData(DateTime.Now);
Binding myBinding = new Binding("MyDataProperty");
myBinding.Source = myDataObject;
myText.SetBinding(TextBlock.TextProperty, myBinding);
See more at http://msdn.microsoft.com/en-us/library/ms742863.aspx
-- Edit Note I don't have access to a WP8 Emulator to test this ---
In the view model it looks like this:
public List<string> Members
{
get { return _Members; }
set { _Members = value; OnPropertyChanged(); }
}
public MainVM()
{
// Simulate Asychronous access, such as to a db.
Task.Run(() =>
{
Thread.Sleep(2000);
Members = new List<string>() {"Alpha", "Beta", "Gamma", "Omega"};
});
}
The code behind on the main page sets the datacontext (shared with all the child controls) as such:
public MainWindow()
{
InitializeComponent();
// Set the windows data context so all controls can have it.
DataContext = new MainVM();
}
The Mainpage Xaml to bind to members is like this
<Button Height="30"
Width="80"
Margin="10"
DataContext="{Binding Members}"
Content="{Binding Path=[0] }" />
<Button Height="30"
Width="80"
Margin="10"
DataContext="{Binding Members}"
Content="{Binding Path=[1] }" />
<Button Height="30"
Width="80"
Margin="10"
DataContext="{Binding Members}"
Content="{Binding Path=[2] }" />
<Button Height="30"
Width="80"
Margin="10"
DataContext="{Binding Members}"
Content="{Binding Path=[3] }" />
The result is this visually:
I based this on my blog article Xaml: ViewModel Main Page Instantiation and Loading Strategy for Easier Binding for more info and a fuller example.
I think your best bet is going to be to use a collection of strings and bind to that collection. You can either change the collection when a toggle is switched, or keep 6 collections and bind to the collection that is for the toggle.
Xaml:
<ItemsControl x:Name="Buttons" ItemsSource="{Binding ButtonTextCollection}">
<ItemsControl.ItemsPanel>
<toolkit:WrapPanel/>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Width="100" Height="70" Content="{Binding}" Click="OnButtonClick"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Your code-behind would have the event handler for your button click
private void OnButtonClick(object sender, RoutedEventArgs e)
{
var text = ((Button) sender).Content.ToString();
// Send the text
}
Your ViewModel would hold the ButtonTextCollection property and would change based on the toggle.
public ICollection<string> ButtonTextCollection
{
get { return _buttonTextCollection; }
set
{
_buttonTextCollection = value;
OnPropertyChanged("ButtonTextCollection");
}
}
When you want to change the text, you would change the ButtonTextCollection
public void ChangeButtonText()
{
ButtonTextCollection = new Collection<string> {"A", "B",...};
}

Categories

Resources