How do I call button inside wpf data template with command - c#

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();
}
}
}

Related

Why is my data binding in .NET with WinUi3 not working?

MainWindow.xaml
<Window
x:Class="Prüfstand_Gallerie.MainWindow"
xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation
xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml
xmlns:local="using:Prüfstand_Gallerie"
xmlns:d=http://schemas.microsoft.com/expression/blend/2008
xmlns:mc=http://schemas.openxmlformats.org/markup-compatibility/2006 xmlns:interactivity="using:Microsoft.Xaml.Interactivity" xmlns:core="using:Microsoft.Xaml.Interactions.Core"
mc:Ignorable="d">
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
<TextBlock Text="{x:Bind ViewModel.FirstName}"></TextBlock>
<Button Content="Change Name" Command="{x:Bind ViewModel.ChangeNameCommand}"></Button>
</StackPanel>
</Window>
MainWindow.xaml.cs
namespace Prüfstand_Gallerie
{
public sealed partial class MainWindow : Window
{
public MainWindow()
{
this.InitializeComponent();
}
public MainWindowViewModel ViewModel { get; } = new();
}
}
MainWindowViewModel.cs
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Prüfstand_Gallerie.ViewModels
{
public partial class MainWindowViewModel : ObservableObject
{
[ObservableProperty]
public string firstName = "Jack";
[RelayCommand]
public void ChangeName()
{
FirstName = "Tjark";
}
[RelayCommand]
private void SelectItem(object param)
{
}
}
}
I'm trying to implement the mvvm pattern with winUi3, but the property FirstName is not updating when the button is clicked, though the command is fired and the value changes as I can see while debugging. It does not change in the ui. Where is the problem?
x:Bind is OneTime by default. You need to explicitly set it to OneWay.
<TextBlock Text="{x:Bind ViewModel.FirstName, Mode=OneWay}" />

How to change field to original value using a "reset" button in wpf

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..
}

How I can modify the Selected text of Combobox?

I'm newer to C# for UI WPF and I would like to set the value of Combobox?
cbx1.SelectedItem = "test 1";
This line show me every time null ( not an exception ) but the selectedItem is empty.
<telerik:RadComboBox Background="White" Foreground="{DynamicResource TitleBrush}" x:Name="cbx1" AllowMultipleSelection="True" VerticalAlignment="Center" HorizontalAlignment="Right" Width="200" Grid.Row="1" Grid.Column="0" Margin="0,14,11,14" Height="22"/>
Update :
I think that my question is not clear , I will give an example :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
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 System.Collections.ObjectModel;
namespace WpfApplication2
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
ObservableCollection<Person> myPersonList = new ObservableCollection<Person>();
Person personJobs = new Person("Steve", "Jobs");
Person personGates = new Person("Bill", "Gates");
myPersonList.Add(personJobs);
myPersonList.Add(personGates);
MyComboBox.ItemsSource = myPersonList;
MyComboBox.SelectedItem = personGates;
}
}
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public Person(string firstName, string lastName)
{
FirstName = firstName;
LastName = lastName;
}
}
}
In this code , if myCombobox.displayMemberPath = FirstName , How can I set the selected FirstName???
I do not have Teleriks Combobox, so I am using the standard Combobox here.
You should also know that XAML is very quiet, it do not throw an exception, but you will probably find an error message in the Output window.
This example is following the MVVM pattern. This means that you will find most of the code in the PersonViewModel class (the "View Model") where the properties are bound to the View. (I am not using the Model here, but that could be a data source class).
The PersonViewModel is inheriting the VMBase where the that notifies the View about changes in properties.
So, to your problem: I have added a property "SelectedPerson". This property is bound to the SelectedItem in the control. So each time you change the item in the combobox the SelectedPerson will contain the selected Person object.
I have also added a button "Select Steve" that will, In the PersonViewModel, find the Person object with firstname = "Steve" and set the SelectedPerson to that object. The Combobox will change to "Steve".
Window1.xaml
<Window x:Class="SO65149368.Window1"
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:SO65149368"
mc:Ignorable="d"
Title="Window1" Height="450" Width="800">
<StackPanel>
<ComboBox Name="MyComboBox" Width="300" HorizontalAlignment="Left" Margin="5"
ItemsSource="{Binding myPersonList}"
DisplayMemberPath="FirstName"
SelectedItem="{Binding SelectedPerson, Mode=TwoWay}"/>
<StackPanel Orientation="Horizontal">
<Button x:Name="SelectSteve" Content="Select Steve" Click="SelectSteve_Click"
Margin="5"/>
</StackPanel>
</StackPanel>
</Window>
Window1.xaml.cs
using System.Windows;
namespace SO65149368
{
public partial class Window1 : Window
{
public PersonViewModel PersonViewModel = new PersonViewModel();
public Window1()
{
DataContext = PersonViewModel;
InitializeComponent();
}
private void SelectSteve_Click(object sender, RoutedEventArgs e)
{
PersonViewModel.SelectSteve();
}
}
}
PersonViewModel.cs
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
namespace SO65149368
{
public class PersonViewModel : VMBase
{
public ObservableCollection<Person> myPersonList { get; } = new ObservableCollection<Person>();
public PersonViewModel()
{
Person personJobs = new Person("Steve", "Jobs");
Person personGates = new Person("Bill", "Gates");
myPersonList.Add(personJobs);
myPersonList.Add(personGates);
SelectedPerson = personGates;
//MyComboBox.ItemsSource = myPersonList;
//MyComboBox.SelectedItem = personGates;
}
public Person SelectedPerson
{
get { return _selectedPerson; }
set
{
Set(ref _selectedPerson, value);
Debug.WriteLine("Selected person: " + SelectedPerson.FirstName + " " + SelectedPerson.LastName);
}
}
private Person _selectedPerson;
public void SelectSteve()
{
SelectedPerson = myPersonList.FirstOrDefault(p => p.FirstName == "Steve");
}
}
}
VMBase.cs
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace SO65149368
{
public abstract class VMBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected bool Set<T>(ref T field, T newValue, [CallerMemberName] string propertyName = null)
{
if (!EqualityComparer<T>.Default.Equals(field, newValue))
{
field = newValue;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
return true;
}
return false;
}
}
}

Binds not updating when messaging between view models using MVVMLight.Messaging

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");
}

How to change Text property with ICommand C# XAML

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.

Categories