I'm currently playing with wpf for the first time and I'm coming into some issues. I cannot figure out how to reference the wpf label element. I changed my label name to "label1" and try referencing it in my c# code, but alas no result just errors such as.
xaml
<Controls:MetroWindow x:Class="Rustomatic.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Rustomatic"
Height="350"
Width="525" >
<Grid>
<Label x:Name="label1" Content="Label" HorizontalAlignment="Left" Margin="229,128,0,0" VerticalAlignment="Top"/>
</Grid>
<Window.InputBindings>
<KeyBinding Gesture="F5" Command="{Binding Hit}" />
</Window.InputBindings>
c#
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 MahApps.Metro.Controls;
namespace Rustomatic
{
public partial class MainWindow : MetroWindow
{
label1.content = "hi";
}
public class Hit
{
}
}
Please take it lightly I was an intermediate at C# once but I haven't used it in a couple of years.
You give names to elements in xaml by using x:Name, this will cause them to be publicly named in designer generated cs-file (it is made out of xaml) and you can access them as you did it in past in winforms.
This code doesn't makes any sense:
public partial class MainWindow : MetroWindow
{
label1.content = "hi";
}
You can't access label1 like this. You have to do it in the property getter/setter or method:
public partial class MainWindow : MetroWindow
{
public void SomeMethod()
{
label1.Content = "hi";
}
}
Also, don't remove constructor InitializeComponent() call, otherwise your window will not get initialized. This is important (unless you add partial class in addition to partial class made for you when you add new window to project):
public MainWindow()
{
InitializeComponent();
}
Related
I've used CaliburnMicro to implement data binding for my data grid:
<Window x:Class="TicketDemo.Views.ShellView"
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:TicketDemo.Views"
mc:Ignorable="d" FontSize="20"
Title="ShellView" Height="450" Width="800"
Closing="{Binding Path=OnClose}">
<Grid>
<DataGrid x:Name="Tickets" AlternatingRowBackground="LightGray" CanUserAddRows="True"
AutoGenerateColumns="False"
>
<DataGrid.Columns>
<DataGridTextColumn Header="Title" Binding="{Binding Path=Title}"/>
<DataGridTextColumn Header="Content" Binding="{Binding Path=Content}"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
I tried to use the same data binding to link a method called OnClose() to the Closing event.
using Caliburn.Micro;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using TicketDemo.Models;
namespace TicketDemo.ViewModels
{
class ShellViewModel : Screen
{
public BindableCollection<TicketModel> Tickets { get; set; }
public ShellViewModel()
{
Tickets = SQLiteDataAccess.LoadTickets();
}
public void OnClose(object sender, EventArgs e)
{
MessageBox.Show("Window Closing");
}
}
}
When I debug the program, I get this message:
using Caliburn.Micro;
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.Shapes;
namespace TicketDemo.Views
{
/// <summary>
/// Interaction logic for ShellView.xaml
/// </summary>
public partial class ShellView : Window
{
public ShellView()
{
InitializeComponent();
MessageBox.Show("Hello");
}
}
}
System.Windows.Markup.XamlParseException: ''Provide value on
'System.Windows.Data.Binding' threw an exception.' Line number '9' and
line position '9'.'
InvalidCastException: Unable to cast object of type
'System.Reflection.RuntimeEventInfo' to type
'System.Reflection.MethodInfo'.
The SO post answering a question about this exception relates to buttons, but this is an event, so I don't think it's helpful to resolve my problem.
if you are using caliburn, the event is declared like this:
replace Closing="{Binding Path=OnClose}"
by
cal:Message.Attach="[Event Closing] = [Action OnClose]"
(dont forget to add xmlns:cal="http://www.caliburnproject.org")
in ViewModel you write:
public void OnClose()
{
MessageBox.Show("Window Closing");
}
I have made a list that is a property amnd then given that list values and this is still not working to place in a listview as a itemsource i have no idea how to fix this and get results is there anyone that can show me what im doing wrong here? i am placing the data context in the MainWindow
XAML
<Window x:Class="CRM.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:CRM"
mc:Ignorable="d"
Title="MainWindow" Height="1080" Width="1920">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="0*"/>
</Grid.ColumnDefinitions>
<ListView ItemsSource="{Binding tickets}" Margin="0,10,1075,0" MaxWidth="990"/>
</Grid>
</Window>
MainViewModel:
using API.Objects;
using API.ViewModels;
using System;
using System.Collections.Generic;
using System.Text;
namespace API.ViewModels
{
public class MainViewModel : BaseViewModel
{
int Counter{ get; set; }
List<TicketO> tickets { get; set;}
public MainViewModel()
{
TicketO ticket = new TicketO("Jens", "Svensson", "jenson1234#live.se", "0767942768", "This is working but my box is not", 500);
tickets.Add(ticket);
}
}
}
MainWindow
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 API.ViewModels;
namespace CRM
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new MainViewModel();
}
}
}
Make tickets public, DataContext = this; is missing, refer below link.
How can I bind a List as ItemSource to ListView in XAML?
I have a simple wpf app, that I want to try to use ItemsSource binding from xaml. When I click the button. it should be updated also in the UI, but it doesn't.
Why doesn't it work?
Xaml code:
<Window x:Class="SendRawEthernetPacketsGUI.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid>
<ComboBox HorizontalAlignment="Left" Margin="76,65,0,0" VerticalAlignment="Top" Width="120" ItemsSource="{Binding test}"/>
<Button Content="Button" HorizontalAlignment="Left" Margin="90,171,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/>
</Grid>
C# code:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
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.Shapes;
namespace SendRawEthernetPacketsGUI
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
public ObservableCollection<string> test = new ObservableCollection<string>();
public Window1()
{
InitializeComponent();
DataContext = this;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
test.Add("fdfddf");
}
}
}
It feels kinda stupid to even ask this, but even looking in google didn't help me. So can you?
Your binding never worked in the first place. You can only bind to properties not fields.
Try this instead:
public ObservableCollection<string> test { get; set; }
public Window1()
{
Test = new ObservableCollection<string>();
}
Or if you want some tricky C# 6 magic:
public ObservableCollection<string> test => new ObservableCollection<string>();
This is a function bodied-member and compiles to a read-only property that is initialized to the new ObservableCollection
Caveats/Design Errors:
Note that in both cases you aren't using INotifyPropertyChanged, so wholesale assignments to the collection won't be picked up by the UI. You should also be using PascalCase for your public properties, and using a proper view model instead of binding to the code-behind.
I've got a weird error when trying to create a simple sample using the latest version of Reactive UI.
The window opens and I get a system error
Couldn't find view for 'Hi Bob!'
note: 'Hi Bob!' is the first item in the list.
What am I missing here?
Thanks.
versions
ReactiveUI 6.5.0
Splat 1.6.2
.net 4.5
Sample code
xaml
<Window x:Class="ListBind.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">
<Grid>
<StackPanel Orientation="Horizontal">
<ListBox Name="ListBox1"></ListBox>
</StackPanel>
</Grid>
Code
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 ReactiveUI;
namespace ListBind
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window, IViewFor<ViewModel>
{
public MainWindow()
{
ViewModel = new ViewModel();
DataContext = ViewModel;
InitializeComponent();
this.OneWayBind(ViewModel, m => m.Items, v => v.ListBox1.ItemsSource);
}
public ViewModel ViewModel
{
get { return (ViewModel)GetValue(ViewModelProperty); }
set { SetValue(ViewModelProperty, value); }
}
public static readonly DependencyProperty ViewModelProperty =
DependencyProperty.Register("ViewModel", typeof(ViewModel), typeof(MainWindow), new PropertyMetadata(null));
object IViewFor.ViewModel
{
get { return ViewModel; }
set { ViewModel = (ViewModel)value; }
}
}
public class ViewModel : ReactiveObject
{
public ReactiveList<string> Items = new ReactiveList<string>(new[] { "Hi Bob!", "Two", "Three" });
}
}
The thing with ReactiveUI when you bind to things like a ListBox using the OneWayBind method, is that it will try to automatically apply a custom template for the data based upon the views it finds with Splat.Locator.Resolve. In your case, it is trying to find and build a view based on the "Hi Bob!" ViewModel, which obviously doesn't exist.
What you should do is force it to use a custom data template so that it doesn't try to apply a non-existing template. With a template below, it shouldn't try and resolve a view for you, but rather stick the "Hi Bob!" value into the TextBlock.
<ListBox x:Name="ListBox1">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
There is a slim chance that ReactiveUI will still ignore that (I cannot verify right now), so if that is the case, replace the OneWayBind binding with the traditional ItemSource={Binding Data}.
This question already has answers here:
Passing parameters between viewmodels
(2 answers)
Closed 8 years ago.
Goal:
When you click one of the rows in the lstView_bbb (in Test.xaml), the return value shall be return to the class MainWindow (MainWindow.xaml). And then, the Test.xaml shall be closed.
Problem:
I tried finding a solution that data of "_a" from row shall be transferred to the MainWIndow but it didn't go so well due to performance issue. I want to make it more efficient.
Information:
*I'm using WPF with VS 2013
*The return value is "_a" to the class MainWIndow.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">
<Grid>
<Button x:Name="btn_test" Content="Test" HorizontalAlignment="Left" Margin="348,240,0,0" VerticalAlignment="Top" Width="75" Click="btn_test_Click"/>
</Grid>
</Window>
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 WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private List<aaa> _myList_aaa;
private void btn_test_Click(object sender, RoutedEventArgs e)
{
_myList_aaa = new List<aaa>();
for (int a = 1; a <= 5; a++)
{
aaa myaaa = new aaa();
myaaa._a = a;
myaaa._city = "New Yor";
myaaa._name = "jj jj jj";
_myList_aaa.Add(myaaa);
}
Test myTest = new Test(_myList_aaa);
myTest.ShowDialog();
}
}
public class aaa
{
public int _a { get; set; }
public string _name { get; set; }
public string _city { get; set; }
}
}
---------------------------------------
<Window x:Class="WpfApplication1.Test"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Test" Height="300" Width="300">
<Grid Background="#FFE5E5E5">
<ListView x:Name="lstView_bbb" SelectionMode="Single" ItemsSource="{Binding}" HorizontalAlignment="Left" Height="111" Margin="35,67,0,0" VerticalAlignment="Top" Width="222">
<ListView.View>
<GridView>
<GridViewColumn Header="name" Width="auto" DisplayMemberBinding="{Binding Path=_name}" TextBlock.TextAlignment="Left" />
<GridViewColumn Header="city" Width="auto" DisplayMemberBinding="{Binding Path=_city}" TextBlock.TextAlignment="Center" />
</GridView>
</ListView.View>
</ListView>
</Grid>
</Window>
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.Shapes;
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for Test.xaml
/// </summary>
public partial class Test : Window
{
public Test(IList<aaa> pAAA)
{
InitializeComponent();
lstView_bbb.DataContext = pAAA;
}
}
}
The easiest way is to create a property in Test:
class Test
{
public aaa SelectedItem
{
get
{
return lstView_bbb.SelectedItems[0] as aaa;
}
}
The best way is to use a ViewModel. Assign it to Test and use the same ViewModel in you other form to get the selected value.
Read the related MSDN article.