My WPF Application code generates panels on function call defined in .cs file. There is ItemControl used in code to generates these Panels . I want to move Panels Up or Down.
Example: There are three Panels PanelA, PanelB, PanelC now now there is button with each panel to move it up. Now i selected PanleB. i click on that button and PanelB will move up now they should be like PanelB, PanelA, PanelC
.XAML File:
<ItemsControl x:Name="lstItems" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBox x:Name="txtText" Width="300" Height="100" Text="{Binding Text;, Mode=TwoWay}" FontSize="{Binding FontSize, Mode=OneWay}" />
<Slider Minimum="10" Maximum="30" Value="{Binding FontSize, Mode=TwoWay}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
.CS File:
public partial class MainWindow : Window
{
protected ObservableCollection<MyPanel> texts = new ObservableCollection<MyPanel>();
public MainWindow()
{
InitializeComponent();
texts.Add(new MyPanel() { Text = "Test 1" });
texts.Add(new MyPanel() { Text = "Test 2" });
lstItems.ItemsSource = texts;
}
}
public class MyPanel : INotifyPropertyChanged
{
private string _id;
private string _text;
private double _fontSize = 10;
public string Id
{
get { return _id; }
set
{
if (value != _id)
{
_id = value;
NotifyPropertyChanged();
}
}
}
public string Text
{
get { return _text; }
set
{
if (value != _text)
{
_text = value;
NotifyPropertyChanged();
}
}
}
public double FontSize
{
get { return _fontSize; }
set
{
if (value != _fontSize)
{
_fontSize = value;
NotifyPropertyChanged();
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged(String propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
EDIT:
XAML FILE:
<ItemsControl x:Name="lstItemsClassM" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<ComboBox x:Name="cboOccupation" IsEditable="False" HorizontalAlignment="Left"
Text="{Binding Path=Alignment, Mode=TwoWay}"
Margin="4" Width="140">
<ComboBoxItem>Right</ComboBoxItem>
<ComboBoxItem>Left</ComboBoxItem>
</ComboBox>
<Button Content="Move Up" Click="Button_Click_1" Tag="{Binding PKId}"/>
<Button Content="{Binding Alignment, Mode=TwoWay}" Click="Button_Click" Tag="{Binding PKId}" SourceUpdated="Button_SourceUpdated" />
<TextBox x:Name="txtText" Width="300" Height="100" Text="{Binding Text;, Mode=TwoWay}" FontSize="{Binding FontSize, Mode=OneWay}" TextAlignment="{Binding Alignment, Mode=OneWay}" />
<Slider Minimum="10" Maximum="30" Value="{Binding FontSize, Mode=TwoWay}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
.CS FILE:
public partial class Window2 : Window
{
protected ObservableCollection<ClassM> texts = new ObservableCollection<ClassM>();
int dv;
public Window2()
{
InitializeComponent();
dv=1;
texts.Add(new ClassM() { PKId=dv, Text = "Test 1" });
dv=2;
texts.Add(new ClassM() { PKId=dv, Text = "Test 2" });
lstItemsClassM.ItemsSource = texts;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
var myValue = ((Button)sender).Tag;
foreach (var f in texts.ToList())
{
if (f.PKId.ToString() == myValue.ToString())
{
f._alignment = "Right";
MessageBox.Show(f._alignment);
}
}
}
private void Button_SourceUpdated(object sender, DataTransferEventArgs e)
{
var myValue = ((Button)sender).Tag;
foreach (var f in texts.ToList())
{
if (f.PKId.ToString() == myValue.ToString())
{
f._alignment = "Right";
MessageBox.Show(f._alignment);
}
}
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
var myValue = ((Button)sender).Tag;
foreach (var f in texts.ToList())
{
if (f.PKId.ToString() == myValue.ToString())
{
int s = f.PKId + 1;
texts.Move(f.PKId , s);
MessageBox.Show(f.PKId +" &&&&& " + s );
}
}
}
}
public class ClassM : INotifyPropertyChanged
{
private string _id;
private int _pkid;
private string _text;
private double _fontSize = 10;
public bool _isChecked { get; set; }
public string _alignment="Left";
public int PKId
{
get { return _pkid; }
set
{
if (value != _pkid)
{
_pkid = value;
NotifyPropertyChanged();
}
}
}
public string Id
{
get { return _id; }
set
{
if (value != _id)
{
_id = value;
NotifyPropertyChanged();
}
}
}
public bool IsChecked
{
get { return _isChecked; }
set
{
if (value != _isChecked)
{
_isChecked = value;
NotifyPropertyChanged();
}
}
}
public string Text
{
get { return _text; }
set
{
if (value != _text)
{
_text = value;
NotifyPropertyChanged();
}
}
}
public double FontSize
{
get { return _fontSize; }
set
{
if (value != _fontSize)
{
_fontSize = value;
NotifyPropertyChanged();
}
}
}
public string Alignment
{
get { return _alignment; }
set
{
if (value != _alignment)
{
_alignment = value;
NotifyPropertyChanged();
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged(String propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
Use the ObservableCollection's Move method:
private void Swap(MyPanel a, MyPanel b)
{
var indexA = texts.IndexOf(a);
var indexB = texts.IndexOf(b);
texts.Move(a,b);
}
Create the Command in your MainWindow, say MovePanelCommand and bind the Button commmand to this command and send the current item as the command parameter
<StackPanel Orientation="Vertical">
<TextBox x:Name="txtText" Width="300" Height="100" Text="{Binding Text;, Mode=TwoWay}" FontSize="{Binding FontSize, Mode=OneWay}" />
<Slider Minimum="10" Maximum="30" Value="{Binding FontSize, Mode=TwoWay}" />
<Button Command="{Binding DataContext.MovePanelCommand, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" CommandParamter="{Binding}"/>
</StackPanel>
Now in command handler you will get your Panel you want to move up
private void MovePanelCommandHandler(object param)
{
MyPanel panel = param as MyPanel;
// Just move the panel one index up with validation if it is a first panel
}
Related
I'm trying to group various sliders elements to work together. In example if I have two elements, both are set to 50 (values goes from 0 to 100), the sum of the values must be always 100, so if I set one of the sliders to value 70, the other one must decrease dynamically to 30 value.
<ListView x:Name="listView"
ItemSource="myList">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Slider x:Name="slider"
Maximum="100"
Minimum="0"
Value="{Binding MyValue}"
HorizontalOptions="FillAndExpand"
MinimumTrackColor="Black"
MaximumTrackColor="Black"
ThumbColor="{StaticResource myColor}"
ValueChanged="OnValueChanged"
PropertyChanging="ChangingSliderValue"/>
<Label Text="{Binding Source={x:Reference slider}, Path=Value, StringFormat='{0:0}'}"
FontSize="Medium"
FontAttributes="Bold"
HorizontalOptions="End"
WidhtRequest="40"/>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
The C# class of my objects is
public class MyClass : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private int _value;
private string _name;
private bool _someBool;
public int MyValue { get {return _value;} set {_value = value;} }
public string Name { get {return _name;} set {_name = value;} }
public bool SomeBool { get {return _someBool;} set {_someBool = value; OnPropertyChanged();} }
void OnPropertyChanged ([CallerMemberName] string propertyName = null)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
And part of the class of the Xaml page is:
namespace MyApp
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class SliderPage: ContentPage
{
private ObservableCollection<MyClass> list = new ObservableCollection<MyClass>();
...
public SliderPage ()
{
InitializeComponent();
InitList();
listView.ItemsSource = list;
...
}
private void InitList () ...
private void ChangingSliderValue (object sender, PropertyChangedEventArgs e)
{
//Code to stick together the slider...
}
}
Any suggestion of how to achieve my goal?
work but is not showing dynamically
You need to implement the interface INotifyPropertyChanged on property MyValue so that the element will update in runtime .
By the way , since you had used data binding in your project . It would be better to handle logic in ViewModel. So you could modify the code like following
in Xmal
<ListView
ItemsSource="{Binding MySource}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal" HeightRequest="300" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
<Slider x:Name="slider"
Maximum="100"
Minimum="0"
Value="{Binding MyValue,Mode=TwoWay}"
HorizontalOptions="FillAndExpand"
MinimumTrackColor="Black"
MaximumTrackColor="Black"/>
<Label Text="{Binding Source={x:Reference slider}, Path=Value, StringFormat='{0:0}'}"
FontSize="20"
FontAttributes="Bold"
WidthRequest="40"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
in Code behind
Model
public class MyClass : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public int Id { get; set; } // add this property to index the slider
private int _value;
private string _name;
private bool _someBool;
public int MyValue {
get
{
return _value;
}
set
{
if(_value!=value)
{
_value = value;
OnPropertyChanged("MyValue");
}
}
}
public string Name { get { return _name; } set { _name = value; } }
public bool SomeBool { get { return _someBool; } set { _someBool = value; OnPropertyChanged("SomeBool"); } }
void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
ViewModel
public class MyViewModel
{
public ObservableCollection<MyClass> MySource { get; set; }
bool isFirstLoad = true;
public MyViewModel()
{
MySource = new ObservableCollection<MyClass>() {
new MyClass(){MyValue = 50,Id=0 },
new MyClass(){MyValue = 50,Id=1 },
};
foreach (MyClass model in MySource)
{
model.PropertyChanged += Model_PropertyChanged;
}
}
private void Model_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName== "MyValue")
{
//handle your logic here as you need
MyClass model = sender as MyClass;
foreach (MyClass item in MySource)
{
if (model.Id != item.Id)
{
item.MyValue = 100 - model.MyValue;
}
}
}
}
}
ContentPage
public xxxPage()
{
InitializeComponent();
BindingContext = new MyViewModel();
}
I want to make a text Box Visible when clicking a DataGrid Column. I use this text box for description of a data Grid column
My two column has grid view (Item and Amount columns)
<DataGrid>
<DataGrid.Columns>
<DataGridTemplateColumn Header="Item" Width="*">
<DataGridTemplateColumn.CellTemplate>
<TextBlock Text="{Binding Item}" VerticalAlignment="Center"/>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
<DataGrid.Columns>
<DataGridTemplateColumn Header="Amount" Width="*">
<DataGridTemplateColumn.CellTemplate>
<TextBlock Text="{Binding Amount}" VerticalAlignment="Center"/>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
I want get the sum of Column [Amount] and show it on a textbox, that is visible only when I click [Amount] Column
Please try the next code:
1. Xaml:
<Window x:Class="DataGridSoHelpAttempt.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dataGridSoHelpAttempt="clr-namespace:DataGridSoHelpAttempt"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
Title="MainWindow" Height="350" Width="525" x:Name="This">
<Window.DataContext>
<dataGridSoHelpAttempt:MainViewModel/>
</Window.DataContext>
<Grid x:Name="MyGrid">
<DataGrid x:Name="MyDataGrid" ItemsSource="{Binding DataSource}" AutoGenerateColumns="False">
<i:Interaction.Behaviors>
<dataGridSoHelpAttempt:ColumnSelectingBehavior TotalPresenterVisibility="{Binding TotalsVisibility, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</i:Interaction.Behaviors>
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
<DataGridTextColumn Header="Comments" Binding="{Binding Comments}" Width="150"/>
<DataGridTextColumn Header="Price (click to see total)" Binding="{Binding Price, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
<StackPanel HorizontalAlignment="Stretch" VerticalAlignment="Bottom">
<TextBlock Visibility="{Binding TotalsVisibility, UpdateSourceTrigger=PropertyChanged}">
<Run Text="Total price:"></Run>
<Run Text="{Binding TotalValue, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}"></Run>
</TextBlock>
</StackPanel>
</Grid></Window>
2. View models and models code:
public class MainViewModel:BaseObservableObject
{
private Visibility _visibility;
private ICommand _command;
private Visibility _totalsVisibility;
private double _totalValue;
public MainViewModel()
{
Visibility = Visibility.Collapsed;
TotalsVisibility = Visibility.Collapsed;
DataSource = new ObservableCollection<BaseData>(new List<BaseData>
{
new BaseData {Name = "Uncle Vania", Description = "A.Chekhov, play", Comments = "worth reading", Price = 25},
new BaseData {Name = "Anna Karenine", Description = "L.Tolstoy, roman", Comments = "worth reading", Price = 35},
new BaseData {Name = "The Master and Margarita", Description = "M.Bulgakov, novel", Comments = "worth reading", Price = 56},
});
}
public ICommand Command
{
get
{
return _command ?? (_command = new RelayCommand(VisibilityChangingCommand));
}
}
private void VisibilityChangingCommand()
{
Visibility = Visibility == Visibility.Collapsed ? Visibility.Visible : Visibility.Collapsed;
}
public ObservableCollection<BaseData> DataSource { get; set; }
public Visibility Visibility
{
get { return _visibility; }
set
{
_visibility = value;
OnPropertyChanged();
}
}
public ObservableCollection<BaseData> ColumnCollection
{
get { return DataSource; }
}
public Visibility TotalsVisibility
{
get { return _totalsVisibility; }
set
{
_totalsVisibility = value;
OnPropertyChanged();
}
}
public double TotalValue
{
get { return ColumnCollection.Sum(x => x.Price); }
}
}
public class BaseData:BaseObservableObject
{
private string _name;
private string _description;
private string _comments;
private int _price;
public virtual string Name
{
get { return _name; }
set
{
_name = value;
OnPropertyChanged();
}
}
public virtual object Description
{
get { return _description; }
set
{
_description = (string) value;
OnPropertyChanged();
}
}
public string Comments
{
get { return _comments; }
set
{
_comments = value;
OnPropertyChanged();
}
}
public int Price
{
get { return _price; }
set
{
_price = value;
OnPropertyChanged();
}
}
}
3. Behavior code:
public class ColumnSelectingBehavior : Behavior<DataGrid>
{
public static readonly DependencyProperty TotalPresenterVisibilityProperty = DependencyProperty.Register(
"TotalPresenterVisibility", typeof (Visibility), typeof (ColumnSelectingBehavior), new PropertyMetadata(Visibility.Collapsed));
public Visibility TotalPresenterVisibility
{
get { return (Visibility) GetValue(TotalPresenterVisibilityProperty); }
set { SetValue(TotalPresenterVisibilityProperty, value); }
}
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.Sorting += AssociatedObjectOnSorting;
}
private void AssociatedObjectOnSorting(object sender, DataGridSortingEventArgs dataGridSortingEventArgs)
{
var columnSortMemberPath = dataGridSortingEventArgs.Column.SortMemberPath;
if(columnSortMemberPath != "Price")
return;
TotalPresenterVisibility = TotalPresenterVisibility == Visibility.Visible
? Visibility.Collapsed
: Visibility.Visible;
}
protected override void OnDetaching()
{
base.OnDetaching();
AssociatedObject.Sorting -= AssociatedObjectOnSorting;
}
}
4. BaseObservableObject code (for .net 4.5):
public class BaseObservableObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
var handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
protected virtual void OnPropertyChanged<T>(Expression<Func<T>> raiser)
{
var propName = ((MemberExpression)raiser.Body).Member.Name;
OnPropertyChanged(propName);
}
protected bool Set<T>(ref T field, T value, [CallerMemberName] string name = null)
{
if (!EqualityComparer<T>.Default.Equals(field, value))
{
field = value;
OnPropertyChanged(name);
return true;
}
return false;
}
}
I'll glad to help in case you will have problems wit the code. Regards.
My WPF Application code generates panels on function call defined in .cs file. There is ItemControl used in code to generates these Panels . I want to to change text Alignment of text of Textbox defined in selected panel via it's button. Query: I clicked button and alignment of select panel TextBox change from left to rightand from right to left, Now implementation of Alignment sets if select slider to move. Here code is:
XAML FILE
<ItemsControl x:Name="lstItemsClassM">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<Button Content="{Binding Alignment, Mode=TwoWay}"
Click="Button_Click"
Tag="{Binding PKId}" />
<TextBox x:Name="txtText"
Width="300"
Height="100"
Text="{Binding Text, Mode=TwoWay}"
FontSize="{Binding FontSize, Mode=OneWay}"
TextAlignment="{Binding Alignment, Mode=OneWay}" />
<Slider Minimum="10"
Maximum="30"
Value="{Binding FontSize, Mode=TwoWay}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
.CS FILE
protected ObservableCollection<ClassM> texts = new ObservableCollection<ClassM>();
int dv;
public Window2()
{
InitializeComponent();
dv=1;
texts.Add(new ClassM() { PKId=dv, Text = "Test 1" });
dv=2;
texts.Add(new ClassM() { PKId=dv, Text = "Test 2" });
lstItemsClassM.ItemsSource = texts;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
var myValue = ((Button)sender).Tag;
foreach (var f in texts.ToList())
{
if (f.PKId.ToString() == myValue.ToString())
{
f._alignment = "Right";
MessageBox.Show(f._alignment);
}
}
}
}
public class ClassM : INotifyPropertyChanged
{
private string _id;
private int _pkid;
private string _text;
private double _fontSize = 10;
public string _alignment="Left";
public int PKId
{
get { return _pkid; }
set
{
if (value != _pkid)
{
_pkid = value;
NotifyPropertyChanged();
}
}
}
public string Id
{
get { return _id; }
set
{
if (value != _id)
{
_id = value;
NotifyPropertyChanged();
}
}
}
public string Text
{
get { return _text; }
set
{
if (value != _text)
{
_text = value;
NotifyPropertyChanged();
}
}
}
public double FontSize
{
get { return _fontSize; }
set
{
if (value != _fontSize)
{
_fontSize = value;
NotifyPropertyChanged();
}
}
}
public string Alignment
{
get { return _alignment; }
set
{
if (value != _alignment)
{
_alignment = value;
NotifyPropertyChanged();
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged(String propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
Alignment means Textbox.Text Alignment left to right or right to left
The best solution is use RichTextBox to align your text. If you wanna i could sugest one implementation to read a literal string and format.
I want change number from ComboBox and change value in TextBox.
(For example I have number =2 and content at "lblblblb" ofc. this is in ObservableCollection<string>, so I to call ContentWithListView[SelectNumberStep])
ReadPage.xaml
<TextBox HorizontalAlignment="Left" Margin="580,154,0,0"
TextWrapping="Wrap" Text="{Binding ContentWithListView[SelectNumberStep],Mode=TwoWay}"
VerticalAlignment="Top" Width="725" Height="82"/>
<ComboBox HorizontalAlignment="Left" Margin="440,154,0,0"
ItemsSource="{Binding NumberStep,Mode=TwoWay}"
SelectedItem="{Binding SelectNumberStep,Mode=TwoWay}"
VerticalAlignment="Top" Width="95" Height="77" />
How I change content in TextBox from CombBox numbers?
ReadViewModel.cs
private ObservableCollection<string> contentWithListView;
public ObservableCollection<string> ContentWithListView
{
get
{
return this.contentWithListView;
}
set
{
this.contentWithListView = value;
}
}
private ObservableCollection<int> stepNumber;
public ObservableCollection<int> NumberStep
{
get
{
return this.stepNumber;
}
set
{
this.stepNumber = value;
}
}
private int selectNumberStep;
public int SelectNumberStep
{
get
{
return this.selectNumberStep;
}
set
{
this.selectNumberStep = value;
}
}
previous answer doesn't integrate the fact he textbox content have to be in TwoWays so, in such scenario, you could consolidate your properties with the INotifyPropertyChanged interface like that:
Xaml part
<StackPanel d:DataContext="{d:DesignInstance Type=classes:StackOverFlowX }">
<TextBox Text="{Binding Content, Mode=TwoWay}"/>
<ComboBox ItemsSource="{Binding NumberStep, Mode=TwoWay}"
SelectedItem="{Binding SelectNumberStep,Mode=TwoWay}"/>
</StackPanel>
Class
using System.ComponentModel;
using System.Runtime.CompilerServices;
public class StackOverFlowX : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public StackOverFlowX()
{
}
private ObservableCollection<string> contentWithListView;
public ObservableCollection<string> ContentWithListView
{
get
{
return this.contentWithListView;
}
set
{
this.contentWithListView = value;
OnPropertyChanged();
}
}
private ObservableCollection<int> stepNumber;
public ObservableCollection<int> NumberStep
{
get
{
return this.stepNumber;
}
set
{
this.stepNumber = value;
OnPropertyChanged();
}
}
private int selectNumberStep;
public int SelectNumberStep
{
get
{
return this.selectNumberStep;
}
set
{
this.selectNumberStep = value;
OnPropertyChanged();
OnPropertyChanged("Content");
}
}
private string _content;
public string Content
{
get
{
return contentWithListView[this.SelectNumberStep];
}
set
{
this._content = value;
if (contentWithListView.IndexOf(value) > -1)
{
SelectNumberStep = contentWithListView.IndexOf(value);
OnPropertyChanged("SelectNumberStep");
}
OnPropertyChanged();
}
}
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
var eventHandler = this.PropertyChanged;
if (eventHandler != null)
{
eventHandler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
I would change your view model code around, so that the text box binds to a scalar string value which is updated on the SelectNumberStep change:
public string Content
{
get
{
// bounds checking here..
return contentWithListView[this.SelectNumberStep];
}
}
public int SelectNumberStep
{
get
{
return this.selectNumberStep;
}
set
{
this.selectNumberStep = value;
this.NotifyOfPropertyChange(() => this.SelectNumberStep);
this.NotifyOfPropertyChange(() => this.Content);
}
}
<TextBox Text="{Binding Content}" ... />
I feel like i'm really close to getting this to work. I have a calender, I want the user to be able to pick a month from a combobox and show the calender for that date. Right now nothing is being displayed no matter what I choose from the combobox. I can get it to work by using a listbox and a button event but its not really updating its just clearing and displaying the new month choosen. It's not the right way to do it. I've put a lot of time into this and if anybody can look at and maybe give me some pointers i'd really appreciate it.
--------Model Class---------
public partial class SchedulePage : Page, INotifyPropertyChanged
{
public int pick2;
public event PropertyChangedEventHandler PropertyChanged;
MainWindow _parentForm;
public int pick;
Schedule sched = new Schedule();
static GregorianCalendar _gc = new GregorianCalendar();
public SchedulePage(MainWindow parentForm)
{
InitializeComponent();
// this.PropertyChanged += comboMonth_SelectionChanged;
pick = Convert.ToInt32(comboMonth.SelectedItem);
_parentForm = parentForm;
}
public void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
private int _nameofmonth ;
public int NameofMonth
{
get
{
return this._nameofmonth;
}
set
{
if (value != this._nameofmonth)
{
this._nameofmonth = value;
NotifyPropertyChanged("NameofMonth");
}
}
}
// void TheViewModel_PropertyChanged(object src, PropertyChangedEventArgs e)
private void comboMonth_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
//{
// if (e.PropertyName == "NameofMonth")
// {
//var date = new DateTime(2011, 11, 1);
//makeCalender(date);
_parentForm.bindings.schedule.Clear();
var t = new List<Schedule>();
DateTime curr = DateTime.Now;
int jeez = comboMonth.SelectedIndex+1;
// comboMonth.Items.Add(curr.Month);
DateTime newcurr = new DateTime(2011, NameofMonth+1, 1);
// pickdate = datePickercal.SelectedDate;
// DateTime newcurr = new DateTime(curr.Year, curr.Month, 1);
var cal = System.Globalization.DateTimeFormatInfo.CurrentInfo.Calendar;
var ms = cal.GetWeekOfYear(new DateTime(newcurr.Year, newcurr.Month, 1), System.Globalization.CalendarWeekRule.FirstDay, System.DayOfWeek.Sunday);
for (var i = 1; newcurr.Month == NameofMonth+1; newcurr = newcurr.AddDays(1))
{
var month_week = (newcurr.Day / 7);
sched.MonthWeek = newcurr.GetWeekOfMonth().ToString();
sched.Month = newcurr.Month.ToString();
sched.Year = newcurr.Year.ToString();
sched.day = newcurr.Day.ToString();
sched.WeekOfYear = cal.GetWeekOfYear(newcurr, System.Globalization.CalendarWeekRule.FirstDay, DayOfWeek.Sunday).ToString();
sched.dayofweek = newcurr.DayOfWeek.ToString();
t.Add(sched);
_parentForm.bindings.schedule.Add(new Schedule { WeekNo = newcurr.GetWeekOfMonth() - 1, WeekDay = (int)newcurr.DayOfWeek, day = newcurr.Day.ToString() });
}
lblDate.Content = (newcurr.Month - 1) + "/" + newcurr.Year;
//testGrid.ItemsSource = t;
comboMonth.DataContext = _parentForm.bindings;
DataContext = _parentForm.bindings;
// }
}
----Part of the XAML------
<ComboBox SelectedIndex="{Binding NameofMonth}" Grid.ColumnSpan="2" Height="23" HorizontalAlignment="Left" Margin="6,0,0,0" Name="comboMonth" VerticalAlignment="Top" Width="120" SelectionChanged="comboMonth_SelectionChanged">
<ComboBoxItem Content="1" IsSelected="False" />
<ComboBoxItem Content="2" />
<ComboBoxItem Content="3" />
<ComboBoxItem Content="4" />
<ComboBoxItem Content="5" />
<ComboBoxItem Content="6" />
<ComboBoxItem Content="7" />
<ComboBoxItem Content="8" />
<ComboBoxItem Content="9" />
<ComboBoxItem Content="10" />
<ComboBoxItem Content="11" IsSelected="False" />
<ComboBoxItem Content="12" />
</ComboBox>
You need to make your poco class that is used within your ObservableCollection implement INotifyChanged.
Example:
<viewModels:LocationsViewModel x:Key="viewModel" />
.
.
.
<ListView
DataContext="{StaticResource viewModel}"
ItemsSource="{Binding Locations}"
IsItemClickEnabled="True"
ItemClick="GroupSection_ItemClick"
ContinuumNavigationTransitionInfo.ExitElementContainer="True">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" Margin="0,0,10,0" Style="{ThemeResource ListViewItemTextBlockStyle}" />
<TextBlock Text="{Binding Latitude, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Style="{ThemeResource ListViewItemTextBlockStyle}" Margin="0,0,5,0"/>
<TextBlock Text="{Binding Longitude, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Style="{ThemeResource ListViewItemTextBlockStyle}" Margin="5,0,0,0" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
public class LocationViewModel : BaseViewModel
{
ObservableCollection<Location> _locations = new ObservableCollection<Location>();
public ObservableCollection<Location> Locations
{
get
{
return _locations;
}
set
{
if (_locations != value)
{
_locations = value;
OnNotifyPropertyChanged();
}
}
}
}
public class Location : BaseViewModel
{
int _locationId = 0;
public int LocationId
{
get
{
return _locationId;
}
set
{
if (_locationId != value)
{
_locationId = value;
OnNotifyPropertyChanged();
}
}
}
string _name = null;
public string Name
{
get
{
return _name;
}
set
{
if (_name != value)
{
_name = value;
OnNotifyPropertyChanged();
}
}
}
float _latitude = 0;
public float Latitude
{
get
{
return _latitude;
}
set
{
if (_latitude != value)
{
_latitude = value;
OnNotifyPropertyChanged();
}
}
}
float _longitude = 0;
public float Longitude
{
get
{
return _longitude;
}
set
{
if (_longitude != value)
{
_longitude = value;
OnNotifyPropertyChanged();
}
}
}
}
public class BaseViewModel : INotifyPropertyChanged
{
#region Events
public event PropertyChangedEventHandler PropertyChanged;
#endregion
protected void OnNotifyPropertyChanged([CallerMemberName] string memberName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(memberName));
}
}
}