I'm trying to set the visibility of tab items in a viewmodel from another viewmodel.
I know the binds are correct for I can set the properties (set to false) in the constructor of the new model and they appear / disappear as I wish (setting some to true).
I know that the messenger is working for I can register to wait for a message in the constructor and send a message in the same constructor which get handled by my message callback and the binds update correctly (I can see tabs that were initially set to false).
I know this is not a race condition because I have set Console write lines and see the order in which each line is called. Create Window -> Register Message callback -> Create message and send.
Sending a message from the first ViewModel to the 2nd my callback in the new viewmodel is called and changes the properties but the view does not change (what is hidden stays hidden).
Method from original viewmodel.
private void GenerateWindowedReport()
{
Console.WriteLine("Executing View Windowed Report");
Window ReportWindow = new ReportWindow();
var msg = new TabVisibility() {
SuitesReportVisible = IncludeReportSuites,
TenantRankingsVisible = IncludeReportTenantRanking,
IndustryReportVisible = IncludeReportIndustry,
SubmarketBreakdownVisible = IncludeReportSubmarket
};
Messenger.Default.Send<TabVisibility>(msg);
ReportWindow.Show();
}
Class TabVisibility
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Analytics_Module.Messages
{
class TabVisibility
{
public bool SuitesReportVisible { get; set; }
public bool TenantRankingsVisible { get; set; }
public bool IndustryReportVisible { get; set; }
public bool SubmarketBreakdownVisible { get; set; }
}
}
New View (Is contained in the new window created in the first method)
<UserControl x:Class="Analytics_Module.Views.TabsReportView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Analytics_Module.Views"
xmlns:viewModel="clr-namespace:Analytics_Module.ViewModels"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
<viewModel:TabsReportViewModel x:Key="vmTabsReport" />
</UserControl.Resources>
<Grid DataContext="{Binding Source={StaticResource vmTabsReport}}">
<TabControl SelectedIndex="{Binding SelectedReportIndex}" >
<TabItem Header="Search Parameteres" >
<ContentControl Margin="0,10,0,5" Name="TabContentReportSearchParameters" />
</TabItem>
<TabItem Header="Suites Report"
Visibility="{Binding VisibilitySuitesReportTab,
Converter={StaticResource BooleanToVisibilityConverter}}"
IsSelected="{Binding VisibilitySuitesReportTab}">
<ContentControl Name="TabContentReportSuites" />
</TabItem>
<TabItem Header="Tenant Rankings" Visibility="{Binding VisibilityTenantRankingsTab,
Converter={StaticResource BooleanToVisibilityConverter}}">
<ContentControl Margin="0,10,0,5" Name="TabContentReportTenantRankings" />
</TabItem>
<TabItem Header="Industry Breakdown" Visibility="{Binding VisibilityIndustryBreakdownTab,
Converter={StaticResource BooleanToVisibilityConverter}}">
<ContentControl Name="TabContentReportIndustryBreakdown" />
</TabItem>
<TabItem Header="Submarket Breakdown" Visibility="{Binding VisibilitySubmarketBreakdownTab,
Converter={StaticResource BooleanToVisibilityConverter}}">
<ContentControl Name="TabContentReportSubmarketBreakdown" />
</TabItem>
</TabControl>
</Grid>
</UserControl>
Code behind of new view
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace Analytics_Module.Views
{
/// <summary>
/// Interaction logic for TabsReportView.xaml
/// </summary>
public partial class TabsReportView : UserControl
{
public TabsReportView()
{
InitializeComponent();
}
}
}
ViewModel giving me issues:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Analytics_Module.Messages;
using Analytics_Module.Utillity;
using MVVMLight.Messaging;
namespace Analytics_Module.ViewModels
{
class TabsReportViewModel : BaseViewModel
{
protected static class TabIndexConstants
{
public const int SearchParameters = 0;
public const int SuitesReport = 1;
public const int TenantRankings = 2;
public const int IndustryBreakdown = 3;
public const int SubmarketBreakdwown = 4;
}
public TabsReportViewModel() : base()
{
Console.WriteLine("TabsreportVM Constructor");
SelectedReportIndex = TabIndexConstants.SearchParameters;
VisibilitySuitesReportTab = false;
VisibilityTenantRankingsTab = false;
VisibilityIndustryBreakdownTab = false;
VisibilitySubmarketBreakdownTab = false;
Messenger.Default.Register<TabVisibility>
(this, (msgTabVisibility) => SetTabVisibility(msgTabVisibility));
Console.WriteLine("Message Registered");
TabVisibility t = new TabVisibility();
t.IndustryReportVisible = true;
t.SubmarketBreakdownVisible = true;
t.SuitesReportVisible = true;
t.TenantRankingsVisible = true;
//SetTabVisibility(t);
//Messenger.Default.Send<TabVisibility>(t);
}
public void SetTabVisibility(TabVisibility msgTabVisibility)
{
Console.WriteLine("Tabs Set Visiblity Callback");
VisibilitySuitesReportTab = (bool) msgTabVisibility.SuitesReportVisible;
VisibilityTenantRankingsTab = (bool) msgTabVisibility.TenantRankingsVisible;
VisibilityIndustryBreakdownTab = (bool) msgTabVisibility.IndustryReportVisible;
VisibilitySubmarketBreakdownTab = (bool)msgTabVisibility.SubmarketBreakdownVisible;
}
public int SelectedReportIndex { get; set; }
public bool VisibilitySuitesReportTab { get; set; }
public bool VisibilityTenantRankingsTab { get; set; }
public bool VisibilityIndustryBreakdownTab { get; set; }
public bool VisibilitySubmarketBreakdownTab { get; set; }
}
}
I found a workaround but this seems more like a hack. All I had to do was to manually trigger the OnPropertyChanged for each property.
public void SetTabVisibility(MessageTabVisibility msgTabVisibility)
{
Console.WriteLine("Tabs Set Visiblity Callback");
VisibilitySuitesReportTab = (bool) msgTabVisibility.SuitesReportVisible;
VisibilityTenantRankingsTab = (bool) msgTabVisibility.TenantRankingsVisible;
VisibilityIndustryBreakdownTab = (bool) msgTabVisibility.IndustryReportVisible;
VisibilitySubmarketBreakdownTab = (bool)msgTabVisibility.SubmarketBreakdownVisible;
Messenger.Default.Unregister<MessageTabVisibility>(this);
Console.WriteLine("Refresh");
OnPropertyChanged("VisibilitySuitesReportTab");
OnPropertyChanged("VisibilityTenantRankingsTab");
OnPropertyChanged("VisibilityIndustryBreakdownTab");
OnPropertyChanged("VisibilitySubmarketBreakdownTab");
}
Related
What I want is to get the CommandParameter data when I click the button in the dynamically created data source.
First I create data for item source, then I bind it with binding, then I try to capture this click event with command.
Mainwindow.xaml
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:lestplay"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800" Loaded="Window_Loaded">
<Window.Resources>
<Style TargetType="ItemsControl" x:Key="den2">
<Setter Property="SnapsToDevicePixels" Value="true" />
<Setter Property="UseLayoutRounding" Value="True" />
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel>
<Button x:Name="lestplaybutton" Command="{Binding DisplayMessageCommand}" CommandParameter="{Binding Id}" Width="100" Height="50" Content="Furkan" />
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<ItemsControl x:Name="le2" Style="{DynamicResource den2}">
</ItemsControl>
</Grid>
</Window>
here is the view i use to bind Icommand
MessageViewModel.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
namespace lestplay
{
public class MessageViewModel
{
public List<Person> Persons { get; set; }
public MessageCommand DisplayMessageCommand { get; set; }
public MessageViewModel()
{
DisplayMessageCommand = new MessageCommand(DisplayMessage);
}
public void DisplayMessage(string messagetext)
{
MessageBox.Show(messagetext);
}
}
}
Person.cs
The class that will hold the data I want
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace lestplay
{
public class Person
{
public string Id { get; set; }
public string Name { get; set; }
public Person(string id, string name)
{
this.Id = id;
this.Name = name;
}
}
}
MessageCommand.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
namespace lestplay
{
public class MessageCommand : ICommand
{
public event EventHandler? CanExecuteChanged;
public Action<string> _execute;
public MessageCommand(Action<string> execute)
{
_execute = execute;
}
public bool CanExecute(object? parameter)
{
return true;
}
public void Execute(object? parameter)
{
_execute.Invoke(parameter as string);
}
}
}
MainWindow.xaml.cs
namespace lestplay
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
List<Person> prn = new List<Person>();
prn.Add(new Person() { Name = "furkan", Id = "ui-148782" });
le2.ItemsSource = prn;
DataContext = new MessageViewModel();
}
}
}
I have a class that has several properties, one of which is editable, another of which is calculated based on the editable value. I want to initialize the editable value with something and allow the user to change it however they wish. However, I also want to have a reset button that puts the original value back into the textbox. I have a third variable that stores the value of the original number. However, I am not sure how I am supposed to access the object when the reset button is clicked to put the value back into the textbox. I've put the relevant code below (if I shouldn't be posting everything please let me know, still new to stackoverflow how-to):
Main Window
C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using HDR_BED_Calc_local.Testers;
using HDR_BED_Calc_local.Helpers;
namespace HDR_BED_Calc_local
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
//var window = new MainWindow();
this.DataContext = new fraction_doses(800, 700, 900, 800, 900, 1, 3);
}
}
}
XAML
<Window x:Class="HDR_BED_Calc_local.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:HDR_BED_Calc_local"
xmlns:uctesters="clr-namespace:HDR_BED_Calc_local.Testers"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<uctesters:fx_tester x:Name="fxtester_UC"/>
</Grid>
</Window>
Custom user control
C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using HDR_BED_Calc_local.Helpers;
namespace HDR_BED_Calc_local.Testers
{
/// <summary>
/// Interaction logic for fx_tester.xaml
/// </summary>
public partial class fx_tester : UserControl
{
public fx_tester()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
// What do I put here??
}
}
}
XAML
<UserControl x:Class="HDR_BED_Calc_local.Testers.fx_tester"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:HDR_BED_Calc_local.Testers"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800" Background="White">
<StackPanel HorizontalAlignment="Center">
<StackPanel Orientation="Horizontal">
<TextBlock xml:space="preserve">Fraction: </TextBlock>
<TextBlock Text="{Binding Path=fraction_number}"></TextBlock>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock xml:space="preserve">Current Dose: </TextBlock>
<TextBox x:Name="curr_fx_tb" Text="{Binding Path=editable_fraction_dose, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"></TextBox>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock xml:space="preserve">EQD2: </TextBlock>
<TextBlock Text="{Binding Path=this_fx_brachy_EQD2, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</StackPanel>
<Button Content="Reset" Click="Button_Click"/>
</StackPanel>
</UserControl>
Helper function with class
C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace HDR_BED_Calc_local.Helpers
{
internal class fraction_doses : INotifyPropertyChanged
{
public int fraction_number { get; set; }
public double alpha_beta { get; }
private double _editable_fraction_dose;
public double editable_fraction_dose
{
get { return _editable_fraction_dose; }
set
{
_editable_fraction_dose = value;
calc_EQD2();
this.OnPropertyChanged("editable_fraction_dose");
}
}
public double actual_fraction_dose { get; }
public double pear_plan_dose { get; }
public double IMRT_plan_dose { get; }
public double max_dose_limit { get; }
public double preferred_dose_limit { get; }
private double _this_fx_brachy_EQD2;
public double this_fx_brachy_EQD2
{
get { return this._this_fx_brachy_EQD2; }
set
{
this._this_fx_brachy_EQD2 = value;
this.OnPropertyChanged("this_fx_brachy_EQD2");
}
}
public event PropertyChangedEventHandler PropertyChanged;
public fraction_doses(double current_dose, double pear_dose, double IMRT_dose, double max_dose_limit, double preferred_dose_limit, int fraction_number, int alpha_beta)
{
this.alpha_beta = alpha_beta;
this.actual_fraction_dose = current_dose;
this.editable_fraction_dose = current_dose;
this.pear_plan_dose = pear_dose;
this.IMRT_plan_dose = IMRT_dose;
this.max_dose_limit = max_dose_limit;
this.preferred_dose_limit = preferred_dose_limit;
this.fraction_number = fraction_number;
}
public void calc_EQD2()
{
// EQD2 is always reported in Gray even though we will be reporting cGy
double dose_Gy = this.editable_fraction_dose/100;
this.this_fx_brachy_EQD2 = Math.Round(1 * dose_Gy * (1+ dose_Gy / alpha_beta)/(1+2/alpha_beta), 2);
}
public void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
if (PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
You can try the following:
private void Button_Click(object sender, RoutedEventArgs e)
{
// What do I put here??
var dc = (fraction_doses ) this.DataContext:
if(dc!=null)
dc.Clear();
}
in your fraction_doses class add the method that clears the properties
public void Clear(){
this.MyProperty = MY_DEFAULT_VALUE;
//clear other properties..
}
This question already has answers here:
How do I update an ObservableCollection via a worker thread?
(7 answers)
Closed 5 years ago.
I try to do some simple task (I guess so). I want to change GUI dynamically, from the for loop.
Let's see my XAML:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<StackPanel Name="MyPanel">
<TextBlock Text="{Binding MyValue}"></TextBlock>
<Button Click="Button_Click">OK</Button>
<ListBox Name="myList" ItemsSource="{Binding MyCollection}" >
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Margin="10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="20"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding A}" Grid.Column="0"/>
<TextBlock Text="{Binding B}" Grid.Column="1"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</Window>
As you can see, I have the Textblock that shows numbers, button that is starting the program and the listbox, that should show the collection items.
After click on the button, the first textblock (bindes MyValue) shows dynamic values, but on the list box I get the next error:
"This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread."
I saw another answers for the error, but cannot understand how to implement it in my case.
Here the C# code:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public static MyModel m;
public MainWindow()
{
m = new MyModel();
InitializeComponent();
MyPanel.DataContext = m;
}
bool flag = false;
private void Button_Click(object sender, RoutedEventArgs e)
{
flag = !flag;
Task.Factory.StartNew(() =>
{
for (int i = 0; i < 5000000; i++)
{
if (flag == false) break;
m.MyValue = i.ToString();
m.MyCollection.Add(new ChartPoint { A = i, B = 2 * i });
}
});
}
}
public class MyModel : INotifyPropertyChanged
{
private string myValue;
public ObservableCollection<ChartPoint> MyCollection { get; set; }
public MyModel()
{
MyCollection = new ObservableCollection<ChartPoint>();
}
public string MyValue
{
get { return myValue; }
set
{
myValue = value;
RaisePropertyChanged("MyValue");
}
}
private void RaisePropertyChanged(string propName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
public class ChartPoint
{
public int A { get; set; }
public int B { get; set; }
}
}
Thanks a lot!
I have changed the Button_Click code a bit, is this you want to achieve, please suggest:
private void Button_Click(object sender, RoutedEventArgs e)
{
flag = !flag;
var list = new List <ChartPoint>();
Task.Factory.StartNew(() =>
{
for (int i = 0; i < 50000000; i++)
{
if (flag == false) break;
m.MyValue = i.ToString();
Dispatcher.BeginInvoke(new Action(() =>
{
m.MyCollection.Add(new ChartPoint
{
A = i,
B = 2 * i
});
}),
DispatcherPriority.Background);
}
});
}
I make a simple weather app. And now i want to change it.
I want to implement a command to a button, and when is pressed, a TextBlock will update with weather info but i can't acces property of TextBlock.
Here is the Command class from Models:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
namespace RemakeWindowsWeather.Models
{
public class Command : ICommand
{
public event EventHandler CanExecuteChanged;
Func<object, bool> canExecuteMethod;
Action<object> executeMethod;
public Command(Func<object, bool> canExecuteMethod, Action<object> executeMethod)
{
this.canExecuteMethod = canExecuteMethod;
this.executeMethod = executeMethod;
}
public bool CanExecute(object parameter)
{
return canExecuteMethod(parameter);
}
public void Execute(object parameter)
{
executeMethod(parameter);
}
}
}
Here is the class from ViewModels where i want to change the property of TextBlock:
using RemakeWindowsWeather.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RemakeWindowsWeather.ViewModels
{
public class CommandViewModel
{
Command ShowWeather { get; set; }
public CommandViewModel()
{
ShowWeather = new Command(canExecuteMethod, executeMethod);
}
private bool canExecuteMethod(object parameter)
{
return true;
}
private async void executeMethod(object parameter)
{
var pos = await LocationManager.GetLocation();
var lat = pos.Coordinate.Latitude;
var lon = pos.Coordinate.Longitude;
var weather = await WeatherProxyMap.GetWeather(lon, lat);
//HERE.. not working
WeatherCondition.Text = weather.main.temp + " " + weather.name;
}
}
}
Here is the XAML:
<Page
x:Class="RemakeWindowsWeather.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:RemakeWindowsWeather"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Name="MyPage">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<StackPanel>
<Button Height="30"
Width="120"
Click="Button_Click"
Content="Get Weather"/>
<TextBlock Name="WeatherCondition"
Margin="0,20,0,20"/>
<TextBox Name="CitySearch"
PlaceholderText="Search for weather.."
Margin="0,20,0,20"/>
<Button Width="120"
Height="30"
Click="Button_Click_1"
Content="Get Weather"/>
<TextBlock Name="CityNameTxtBlock"/>
</StackPanel>
</Grid>
You need to bind your command from the viewmodel in xaml, instead using event handlers in the view.
<Button Width="120"
Height="30"
Command="{Binding ShowWeather}"
Content="Get Weather"/>
Also the command should be public and you need a text property
public Command ShowWeather { get; set; }
public string WeatherText { get; set; }
Then you need to bind the text from the viewmodel in the view.
<TextBlock Name="WeatherCondition" Margin="0,20,0,20" Text="{Binding WeatherText}"/>
also you would need to implement INotifyPropertyChanged in the viewmodel and call it when you modify the text.
WeatherText= weather.main.temp + " " + weather.name;
this.RaisePropertyChanged("WeatherText");
This pretty much basic MVVM which you can read about from here.
All,
I have what i think is the simplest example possible of data binding in silverlight... but clearly even that is too complicated for me :)
The XAML:
<UserControl x:Class="SilverlightApplication1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480">
<ListBox x:Name="rblSessions">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding SessionTitle}" Foreground="Black" FontSize="30" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
The code behind:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace SilverlightApplication1
{
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
List<Sessions> theSessions = makeSessions();
rblSessions.ItemsSource = theSessions;
rblSessions.DataContext = theSessions;
}
public List<Sessions> makeSessions()
{
List<Sessions> theReturn = new List<Sessions>();
for (int i = 0; i < 20; i++)
{
Sessions s = new Sessions() { SessionID = i, SessionTitle = string.Format("title{0}", i) };
theReturn.Add(s);
}
return theReturn;
}
}
public class Sessions
{
public int SessionID;
public string SessionTitle;
}
}
When I run the app, I get a listbox with 20 elements in it, but each element is empty, and only about 5 pixels tall (though I set FontSize to "30")
What am I doing wrong? Help please and thanks
/jonathan
You must make your Session class members into properties in order to use them in a binding. This should fix it:
public class Sessions
{
public int SessionID { get; set; }
public string SessionTitle { get; set; }
}