C# WPF application using data binding, data templates and observable collection - c#

I am making a program in C# WPF using data binding, data templates and observable collection. I am basing my application on the Data Binding Demo from http://msdn.microsoft.com/en-us/library/vstudio/ms771319(v=vs.90).aspx. For some reason I cannot make my program display any data from binding. Debugging tells me that my Records class collection works but on this line:
records_collection_db = (CollectionViewSource)(this.Resources["records_collection_db"]);
my 'records_collection_db' variable in null whereas it should be holding some data. I suspect that that my CollectionViewSource in xaml line is set incorrectly but I don't really know how to fix it. It is my first program in WPF and so I don't have much experience on the subject. At this moment the only visible difference between my code and the one from sample is that my initial window is... a where in the demo it an
Code (or at least shortened version of it):
Record class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.ObjectModel;
using System.ComponentModel;
namespace WpfApplication1
{
public class Record : INotifyPropertyChanged
{
private int Lp;
private string group;
public event PropertyChangedEventHandler PropertyChanged;
public int _Lp
{
get { return this.Lp; }
set { this.Lp = value; OnPropertyChanged("_Lp"); }
}
public string _group
{
get { return this.group; }
set { this.group = value; OnPropertyChanged("_group"); }
}
public Record(int Lp, string group)
{
this.Lp = Lp;
this.group = group;
}
protected void OnPropertyChanged(string property)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
}
}
Initial window
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Data;
using System.Xml;
using System.Configuration;
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
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var newWindow1 = new Audyt_window();
newWindow1.Show();
}
}
}
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:src="clr-namespace:WpfApplication1"
xmlns:System="clr-namespace:System;assembly=Mscorlib"
Title="MainWindow" Height="350" Width="525"
WindowStartupLocation="CenterScreen"
>
<Window.Resources>
<Style x:Key="text_style" TargetType="TextBlock">
<Setter Property="Foreground" Value="#333333" />
</Style>
</Window.Resources>
<Grid>
<Button Content="Start" HorizontalAlignment="Left" Margin="36,36,0,0" VerticalAlignment="Top" Width="178" Height="93" Click="Button_Click"/>
<Button Content="Zamknij" HorizontalAlignment="Left" Margin="202,223,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click_1"/>
<Button Content="Rekordy" HorizontalAlignment="Left" Margin="318,56,0,0" VerticalAlignment="Top" Width="108" Height="52" Click="Button_Click_2" />
<Button Content="Dodaj" HorizontalAlignment="Left" Margin="351,157,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click_3"/>
</Grid>
</Window>
Operational window
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
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;
using System.Data;
using System.Data.SqlClient;
using System.Diagnostics;
using System.ComponentModel;
namespace WpfApplication1
{
public partial class Audyt_window : Window
{
CollectionViewSource records_collection;
private ObservableCollection<Record> records = new ObservableCollection<Record>();
public ObservableCollection<Record> Records
{
get { return this.records; }
set { this.records = value; }
}
public Audyt_window()
{
load_temp_data();
InitializeComponent();
records_collection = (CollectionViewSource)(this.Resources["records_collection"]);
}
private void load_temp_data()
{
Record rek1 = new Record(601, "Gr1", "Pro1", "Pyt1", 600001, "Kat1", false, false);
Record rek2 = new Record(602, "Gr2", "Pro2", "Pyt2", 600002, "Kat2", false, false);
Record rek3 = new Record(603, "Gr3", "Pro3", "Pyt3", 600003, "Kat3", false, false);
this.Records.Add(rek1);
this.Records.Add(rek2);
this.Records.Add(rek3);
}
}
}
<Window x:Class="WpfApplication1.Audyt_window"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Audyt"
xmlns:src="clr-namespace:WpfApplication1"
ResizeMode="NoResize"
SizeToContent="WidthAndHeight"
WindowStartupLocation="CenterScreen"
>
<Window.Resources>
<CollectionViewSource Source="{Binding Source={x:Static Application.Current}, Path=Records}" x:Key="records_collection" />
<Style x:Key="text_style" TargetType="TextBlock">
<Setter Property="Foreground" Value="#333333" />
</Style>
<DataTemplate x:Key="Records_Template" DataType="{x:Type src:Record}">
<Border BorderThickness="2" BorderBrush="Navy" Padding="7" Name="Record_List_Border" Margin="3" Width="345">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="30"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Background="Aqua" Grid.Row="0" Grid.Column="0"
Name="textblock_Lp"
Style="{StaticResource text_style}"
Text="Lp: "
>
</TextBlock>
<TextBlock Background="Azure" Grid.Row="0" Grid.Column="1"
Name="datablock_Lp"
Style="{StaticResource text_style}"
Text="{Binding Path=_Lp}"
>
</TextBlock>
<TextBlock Background="Aqua" Grid.Row="0" Grid.Column="2"
Name="datablock_group"
Style="{StaticResource text_style}"
Text="{Binding Path=_group}"
>
</TextBlock>
</Grid>
</Border>
</DataTemplate>
</Window.Resources>
<Border Padding="10">
<Grid>
<ListBox Name="Hits_View_List" HorizontalAlignment="Left" VerticalAlignment="Top"
Height="525" Width="400" Margin="420,0,0,0"
BorderThickness="2" BorderBrush="DimGray"
ItemsSource="{Binding Source={StaticResource records_collection}}"
>
</ListBox>
</Grid>
</Border>
</Window>

In your Audyt_window you set the source of your binding of the CollectionViewSource to {x:Static Application.Current}, but the Records ObservableCollection is declared inside your Audyt_window
Change:
<CollectionViewSource Source="{Binding Source={x:Static Application.Current}, Path=Records}" x:Key="records_collection" />
To
<CollectionViewSource Source="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Window}, Path=Records}" x:Key="records_collection" />
And it should work I think.

you Name your collectionviewsource
x:Key="records_collection"
and you are searching for records_collection_db... that cant match
records_collection_db = (CollectionViewSource)(this.Resources["records_collection_db"]);
Change the Key or Change the string to the right name

Related

C# WPF ListView control - Problem with binding data

I'm having some trouble binding data to a ListView control. I watched many tutorials where it seems like they did it the way I did here with either binding to a collection or a class that had a collection of items.
When I add the cars in this example nothing is added to the listview control. Anything obvious I have missed here? I have checked that the cars are added to the collection during runtime.
The car class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CarClasses
{
internal class Car
{
string _brand = "";
string _model = "";
public Car(string brand, string model)
{
_brand = brand;
_model = model;
}
public string Brand
{
get { return _brand; }
set { _brand = value; }
}
public string Model
{
get { return _model; }
set { _model = value; }
}
}
}
MainWindow.xaml:
<Window x:Class="GridViewListView.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:GridViewListView"
mc:Ignorable="d"
Title="MainWindow" Height="300" Width="600">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="75"></ColumnDefinition>
<ColumnDefinition Width="2*"></ColumnDefinition>
<ColumnDefinition Width="7*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<ListView x:Name="lvCarList" ItemsSource="{Binding CarCollection }" Grid.Column="2" Width="200" Height="250" SelectionMode="Single" BorderThickness="3" BorderBrush="AliceBlue">
<ListView.Style>
<Style/>
</ListView.Style>
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"></ColumnDefinition>
<ColumnDefinition Width="100"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Grid.Column="0" Content="{Binding Brand}"></Label>
<Label Grid.Row="0" Grid.Column="1" Content="{Binding Model}"></Label>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<StackPanel Grid.Column="0">
<TextBlock Text="Brand" Margin="10,10,0,0"></TextBlock>
<TextBlock Text="Model" Margin="10,10,0,0"></TextBlock>
</StackPanel>
<StackPanel Grid.Column="1" Margin="0,0,0,0">
<TextBox Name="txtBrand" HorizontalAlignment="Left" Width="100" Margin="10,10,0,0"></TextBox>
<TextBox Name="txtModel" HorizontalAlignment="Left" Width="100" Margin="10,10,0,0"></TextBox>
<Button Name="btnAdd" Content="Add" Margin="10, 10,10,10" Click="btnAdd_Click"></Button>
</StackPanel>
</Grid>
</Window>
MainWindow.xaml.cs:
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 CarClasses;
namespace GridViewListView
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
///
public partial class MainWindow : Window
{
List<Car> CarCollection = new List<Car>();
public MainWindow()
{
InitializeComponent();
}
private void btnAdd_Click(object sender, RoutedEventArgs e)
{
Car newCar = new Car(txtBrand.Text, txtModel.Text);
CarCollection.Add(newCar);
txtBrand.Text = "";
txtModel.Text = "";
}
}
}
You should/need to specify the DataContext.
And you need to make the Car's collection a public property. It's currently a field.
And also it should be an ObservableCollection, because it's changed at runtime and changes should be displayed in the UI automatically.
public partial class MainWindow : Window
{
public ObservableCollection<Car> CarCollection { get; } = new ObservableCollection<Car>();
public MainWindow()
{
this.DataContext = this;
InitializeComponent();
}
private void btnAdd_Click(object sender, RoutedEventArgs e)
{
Car newCar = new Car(txtBrand.Text, txtModel.Text);
CarCollection.Add(newCar);
txtBrand.Text = "";
txtModel.Text = "";
}
}

C#/WPF How to make close application button from a ViewModel

So I am new to the whole C#/WPF thing and was wondering how to make a button that when clicked will close the application.
I have tried numerous suggestions from google searches like:
Close Window from ViewModel
WPF Close window with MVVM from ViewModel class
https://web.csulb.edu/~pnguyen/cecs475/pdf/closingwindowmvvm.pdf
https://medium.com/#franklyndejesusmejia/close-a-window-from-viewmodel-using-wpf-and-mvvm-pattern-277ec7ef1805
https://social.msdn.microsoft.com/Forums/vstudio/en-US/17aabea0-4aca-478f-9205-fcd56080b22a/how-to-close-a-window-by-clicking-the-button-using-mvvm?forum=wpf
https://www.youtube.com/watch?v=U7Qclpe2joo&ab_channel=BrianLagunas
None of which seemed to help me out properly. Below I have provided the code I currently have that I made following a tutorial on ViewModel navigation. If more code is needed let me know.
Files:
File List
MainMenuViewModel:
using Creator.Commands;
using Creator.Stores;
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Input;
namespace Creator.ViewModels
{
class MainMenuViewModel : ViewModelBase
{
public ICommand NavigateItemCreateMenuCommand { get; }
public MainMenuViewModel(NavigationStore navigationStore)
{
NavigateItemCreateMenuCommand = new NavigateCommand<ItemCreateMenuViewModel>(navigationStore, () => new ItemCreateMenuViewModel(navigationStore));
}
}
}
MainMenuView: Quit button must close the application
<UserControl x:Class="Creator.Views.MainMenuView"
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:Creator.Views"
mc:Ignorable="d"
d:DesignHeight="720" d:DesignWidth="1280">
<Grid Background="White">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition/>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<DockPanel Background="LightBlue" Grid.Row="1" Grid.Column="1" >
<StackPanel>
<Label Content="Main Menu" HorizontalAlignment="Center" VerticalAlignment="Stretch" FontWeight="Bold" FontFamily="Century Gothic" FontSize="24"/>
<Button Content="Create Item" FontWeight="Bold" FontFamily="Century Gothic" FontSize="18" Margin="20,0,20,5" Padding="0,5,0,5" Command="{Binding NavigateItemCreateMenuCommand}"/>
<Button Content="Quit" FontWeight="Bold" FontFamily="Century Gothic" FontSize="18" Margin="20,0,20,5" Padding="0,5,0,5" VerticalAlignment="Bottom"/>
</StackPanel>
</DockPanel>
</Grid>
</UserControl>
MainWindow.xaml.cs:
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 Creator
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
}
TL;DR:
I need to make the Quit button on MainMenuViewModel/MainMenuView to close the application.
Extend your ViewModel with QuitCommand and do bind it to the Button.
class MainMenuViewModel : ViewModelBase
{
public ICommand NavigateItemCreateMenuCommand { get; }
public ICommand QuitCommand { get; }
public MainMenuViewModel(NavigationStore navigationStore)
{
NavigateItemCreateMenuCommand = new NavigateCommand<ItemCreateMenuViewModel>(navigationStore, () => new ItemCreateMenuViewModel(navigationStore));
QuitCommand = new RelayCommand((par) => { Application.Current.Shutdown(); });
}
}
<Button Content="Quit" FontWeight="Bold" FontFamily="Century Gothic" FontSize="18" Margin="20,0,20,5" Padding="0,5,0,5" VerticalAlignment="Bottom" Command="{Binding QuitCommand}"/>
Find also implementation of RelayCommand in Why RelayCommand
You should use Command to close a running window in the ViewModel.
You can import the currently running MainWindow by handing over the parent control Window to the CommandParameter.
I made a sample for you by using MVVM.
I hope it helps you.
👉Github
Structure
MainMenuView.xaml
<Grid>
<Grid Background="White">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition/>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<DockPanel Style="{StaticResource MAIN.DOCK}">
<StackPanel>
<Label Style="{StaticResource MAIN.LABEL}"/>
<Button Style="{StaticResource BTN.CREATE}"/>
<Button Style="{StaticResource BTN.QUIT}"/>
</StackPanel>
</DockPanel>
</Grid>
</Grid>
MainMenuView.xaml.cs
public partial class MainMenuView : UserControl
{
public MainMenuView()
{
InitializeComponent();
DataContext = new MainMenuViewModel();
}
}
MainMenuViewModel
public class MainMenuViewModel
{
public ICommand QuitCommand { get; set; }
public MainMenuViewModel()
{
QuitCommand = new RelayCommand<object>(QuitApp);
}
private void QuitApp(object obj)
{
if (obj is Window window)
{
window.Close();
}
}
}
MainMenuResource
The whole resource source is in the Github.
<Style TargetType="{x:Type Button}" x:Key="BTN.QUIT">
<Setter Property="Command" Value="{Binding QuitCommand}"/>
<Setter Property="CommandParameter" Value="{Binding RelativeSource={RelativeSource AncestorType=Window}}"/>
<Setter Property="Content" Value="Quit"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="FontFamily" Value="Century Gothic"/>
<Setter Property="FontSize" Value="18"/>
<Setter Property="Margin" Value="20 0 20 5"/>
<Setter Property="Padding" Value="0 5 0 5"/>
<Setter Property="VerticalAlignment" Value="Bottom"/>
</Style>
First i'll create an interface
public interface IClosable
{
Action Close { get;set; }
}
then you're viewmodel should implement this interface
MainWindowViewModel : ICloseable
{
public Action Close { get;set; }
//your code
}
then on the window
public partial class MainMenuView : Window
{
public MainMenuView()
{
InitializeComponent();
DataContext = new MainMenuViewModel();
if(DataContext is IClosable closable)
{
closable.Close += this.Close();
}
}
}
Also unhook the delegate before closing window.
Now invoking Close Action in viewmodel will close window.

ViewModel issue

I need pop up a window which takes time. The button is in Pressed state until the new window is opened. Hence I want to add a wait indicator over the UI window after I click the button and before the the window opens. The code of ViewModel is correct because I referred to a sample code. But why there is no response after I click the button.
The project file URL
https://supportcenter.devexpress.com/attachment/file/5268961b-ce35-4e40-b7c1-e33bffab902b
MainWindow:
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 DevExpress.Xpf.Core;
namespace WaitIndicatorDemo
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : DXWindow
{
public MainWindow()
{
InitializeComponent();
vm = new MainVM();
DataContext = vm;
}
MainVM vm;
private void buttonShow_Click(object sender, RoutedEventArgs e)
{
vm.IsBusy = !vm.IsBusy;
}
}
}
ViewMode:
using DevExpress.Mvvm;
namespace WaitIndicatorDemo
{
public class MainVM
{
private readonly ISplashScreenService _waitIndicatorService;
public virtual bool IsBusy { get; set; }
public MainVM()
{
_waitIndicatorService =
ServiceContainer.Default.GetService<ISplashScreenService>("WaitIndicatorService");
}
protected void OnIsBusyChanged()
{
if (IsBusy)
_waitIndicatorService.ShowSplashScreen();
else
_waitIndicatorService.HideSplashScreen();
}
}
}
Below is the XAML, the comment ones are the original sample code. The checkbox bind to IsBusy. The indicator pop up when the checkbox is checked. I now want to pop up after press the button.
<dx:DXWindow x:Class="WaitIndicatorDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
xmlns:waitIndicatorDemo="clr-namespace:WaitIndicatorDemo"
xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
WindowStartupLocation="CenterScreen" SnapsToDevicePixels="True"
Title="MainWindow" Height="350" Width="525">
<!--DataContext="{dxmvvm:ViewModelSource Type=waitIndicatorDemo:MainVM}"-->
<!--Title="MainWindow" Height="350" Width="525">-->
<Grid Margin="10">
<!--<dxe:CheckEdit Content="Is Busy" IsChecked="{Binding IsBusy}"
VerticalAlignment="Top" HorizontalAlignment="Left" />
<Button Content="Button1" IsEnabled ="{Binding IsBusy, Converter={dxmvvm:BooleanNegationConverter}}"
VerticalAlignment="Top" HorizontalAlignment="Center" Click="Button_Click"/>
<Button Content="Button2" IsEnabled="{Binding IsBusy, Converter={dxmvvm:BooleanNegationConverter}}"
VerticalAlignment="Top" HorizontalAlignment="Right"/>-->
<Button x:Name="buttonShow" Content="Show" HorizontalAlignment="Left" Height="35" Margin="50,70,0,0" VerticalAlignment="Top" Width="75" Click="buttonShow_Click" />
</Grid>
</dx:DXWindow>
You have a few mistakes in your code sample :
1- The method OnIsBusyChanged in your ViewModel is never called.
2- Your XAML doesn't declare any ISplashScreenService object in the Window behaviors, like a DXSplashScreenService for instance.
Here's how you can fix both of those issues.
First, fix the ViewModel.
public class MainVM
{
private readonly ISplashScreenService _waitIndicatorService;
private bool _isBusy;
public virtual bool IsBusy
{
get
{
return _isBusy;
}
set
{
_isBusy = value;
OnIsBusyChanged();
}
}
public MainVM()
{
_waitIndicatorService =
ServiceContainer.Default.GetService<ISplashScreenService>("WaitIndicatorService");
}
protected void OnIsBusyChanged()
{
_waitIndicatorService.SetSplashScreenState("Doing some work...");
if (IsBusy)
_waitIndicatorService.ShowSplashScreen();
else
_waitIndicatorService.HideSplashScreen();
}
}
Then, your XAML.
<dx:DXWindow x:Class="WaitIndicatorDemo.MainWindow"
<!-- ... -->
Title="MainWindow" Height="350" Width="525">
<dxmvvm:Interaction.Behaviors>
<dx:DXSplashScreenService x:Name="WaitIndicatorService">
<dx:DXSplashScreenService.ViewTemplate>
<DataTemplate>
<Grid>
<Border Background="LightGray" CornerRadius="5">
<Border BorderBrush="#FF0072C6" BorderThickness="1" Margin="15" CornerRadius="5">
<Grid>
<ProgressBar BorderThickness="0" Value="{Binding Progress}" Maximum="{Binding MaxProgress}" IsIndeterminate="{Binding IsIndeterminate}" Height="12" />
<TextBlock Text="{Binding State, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</Border>
</Border>
</Grid>
</DataTemplate>
</dx:DXSplashScreenService.ViewTemplate>
</dx:DXSplashScreenService>
</dxmvvm:Interaction.Behaviors>
<Grid Margin="10">
<!-- ... -->
</Grid>
</dx:DXWindow>
This code was mainly taken from the How to: Use DxSplashScreenService sample.

how to make user control return its item?

I have a user control with a canvas on it. I want to be able to reference the canvas element, but I can't.
I tried to create a method in the code-behind to return the canvas, but it doesn't work, because when I need to use it I must create a new instance of the user control and that will contain an empty canvas. I need the canvas that's in the current showing window.
Here is the method that I have created to return the canvas:
public DesignerCanvas ret()
{
return this.MyDesigner;
}
Here is the XAML:
<UserControl x:Class="DiagramDesigner.WindowsUserControl"
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:s="clr-namespace:DiagramDesigner"
xmlns:usercontrols="clr-namespace:DiagramDesigner"
xmlns:c="clr-namespace:DiagramDesigner.Controls"
mc:Ignorable="d"
d:DesignHeight="700" d:DesignWidth="1000">
<UserControl.Resources>
<ContextMenu x:Key="DesignerCanvasContextMenu" >
<MenuItem Header="Paste" Command="{x:Static ApplicationCommands.Paste}">
<MenuItem.Icon>
<Image Source="Resources/Images/Paste.png" Width="16"/>
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="Select All" Command="{x:Static s:DesignerCanvas.SelectAll}"/>
</ContextMenu>
</UserControl.Resources>
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="1" Margin="0,10,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<!-- Toolbox -->
<StackPanel Grid.Column="0" Margin="0,0,5,0" >
<usercontrols:UserControl1></usercontrols:UserControl1>
</StackPanel>
<!-- GridSplitter -->
<GridSplitter Focusable="False" Width="2" Background="LightGray"
VerticalAlignment="Stretch" HorizontalAlignment="Right"/>
<!-- Designer -->
<GroupBox Header="Diagram" Grid.Column="1" Margin="3,0,0,0">
<ScrollViewer HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto">
<s:DesignerCanvas Focusable="true" x:Name="MyDesigner"
Background="{StaticResource WindowBackgroundBrush}"
Margin="10" FocusVisualStyle="{x:Null}"
ContextMenu="{StaticResource DesignerCanvasContextMenu}"/>
</ScrollViewer>
</GroupBox>
</Grid>
</Grid>
</UserControl>
and here is my usercontrol.xaml.cs code
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;
namespace DiagramDesigner
{
/// <summary>
/// Interaction logic for WindowsUserControl.xaml
/// </summary>
public partial class WindowsUserControl : UserControl
{
public WindowsUserControl()
{
InitializeComponent();
}
public DesignerCanvas ret()
{
return this.MyDesigner;
}
}
}
the mainwindow.xaml code
<Window x:Class="DiagramDesigner.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:s="clr-namespace:DiagramDesigner"
xmlns:c="clr-namespace:DiagramDesigner.Controls"
xmlns:usercontrols="clr-namespace:DiagramDesigner"
WindowStartupLocation="CenterScreen" WindowState="Maximized"
Title="GEN Diagram Designer"
Height="700" Width="1000" Icon="Resources/Images/coollogo_com-61024358.png">
<Window.Resources>
<ContextMenu x:Key="DesignerCanvasContextMenu">
<MenuItem Header="Paste" Command="{x:Static ApplicationCommands.Paste}">
<MenuItem.Icon>
<Image Source="Resources/Images/Paste.png" Width="16"/>
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="Select All" Command="{x:Static s:DesignerCanvas.SelectAll}"/>
</ContextMenu>
</Window.Resources>
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ContentControl Content="{StaticResource MyToolbar}"/>
<Button Margin="776.346,40.022,75.653,39.977" Click="Button_Click_1" Width="120" Height="40" >Generate Code</Button>
<Grid Grid.Row="1">
<usercontrols:WindowsUserControl Loaded="WindowsUserControl_Loaded">
</usercontrols:WindowsUserControl>
</Grid>
</Grid>
</Window>
my mainwindow.xaml.cs code
using System.Windows;
using System.Collections.Generic;
using System.Xml;
using System.Linq;
namespace DiagramDesigner
{
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
XmlDocument doc = new XmlDocument();
XmlElement elem = doc.CreateElement("code");
doc.AppendChild(elem);
List<DesignerItem> L = new List<DesignerItem>();
foreach (DesignerItem d in ***)
{
L.Add(d);
}
var orderedItems = L.OrderBy(item => DesignerCanvas.GetTop(item)).ToList();
foreach (DesignerItem d in orderedItems)
{
XmlNode ChildNode = doc.ImportNode(d.s.code(), true);
doc.FirstChild.AppendChild(ChildNode);
}
doc.Save(#"D:\code.xml");
}
private void WindowsUserControl_Loaded(object sender, RoutedEventArgs e)
{
}
}
}
in the mainwindow.xaml.cs
the first for each * here where i want to get my canvas
Give your control a name:
<usercontrols:WindowsUserControl Loaded="WindowsUserControl_Loaded" x:Name="someName" />
Then just reference the control using that name:
private void WindowsUserControl_Loaded(object sender, RoutedEventArgs e)
{
var theCanvasFromTheUserControl = someName.ret();
// now do something with theCanvasFromTheUserControl
}

How do I create a XAML binding to a member variable?

I'm new to XAML and data binding. I want to define a GUI control in MainWindow.xaml that gets its data from a member variable in MainWindow.xaml.cs. For simplicity's sake I just made a program that displays a counter as well as a button to increment the counter.
Based on earlier threads I've looked up, I came up with the following code:
MainWindow.xaml.cs
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 XAMLBindingTest
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private int Counter
{
get { return (int)GetValue(CounterProperty); }
set { SetValue(CounterProperty, value); }
}
public static readonly DependencyProperty CounterProperty =
DependencyProperty.Register("Counter", typeof(int), typeof(MainWindow), new PropertyMetadata(null));
public MainWindow()
{
Counter = 0;
InitializeComponent();
}
private void incrementCounter(object sender, RoutedEventArgs e)
{
++Counter;
}
}
}
MainWindow.xaml
<Window x:Class="XAMLBindingTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="140" Width="180">
<Grid>
<StackPanel HorizontalAlignment="Left" VerticalAlignment="Top">
<TextBlock x:Name="txbCounter" HorizontalAlignment="Left" TextWrapping="Wrap" Text="{Binding Counter}" VerticalAlignment="Top"/>
<Button x:Name="btnIncrement" Content="Increment" Width="75" Click="incrementCounter"/>
</StackPanel>
</Grid>
</Window>
This example compiles, but the TextBlock isn't showing a counter value. How do I wire the TextBlock to the Counter member in a correct way?
Try adding a "Name" to your window and binding using "ElementName"
<Window x:Class="XAMLBindingTest.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" Name="UI">
<Grid>
<StackPanel HorizontalAlignment="Left" VerticalAlignment="Top">
<TextBlock x:Name="txbCounter" HorizontalAlignment="Left" TextWrapping="Wrap" Text="{Binding ElementName=UI, Path=Counter}" VerticalAlignment="Top"/>
<Button x:Name="btnIncrement" Content="Increment" Width="75" Click="incrementCounter"/>
</StackPanel>
</Grid>
</Window>
If i understood you correctly:
ItemSource="{Binding Path=TestData, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type common:LayoutAwarePage}}}"
TestData is property of type ObservableCollection declared in .xaml.cs file. ItemSource - is a example property you want bind to.
UPD2:
<ItemsControl ItemSource="{Binding Path=TestData, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type common:LayoutAwarePage}}}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

Categories

Resources