I am trying to create a "notes" app using wpf mvvm. I have a MainWindow containing a DataGrid with data that is bound to an ObservableCollection. In MainWindowView I have a "Find" button which calls FindWindowDialog. In the FindWindowDialog in the textbox, I must enter the text that will be searched and click "Find", after which the DataGrid MainWindowView should hide those lines whose content does not contain the searched text. I don't really know how to do this, after 2 days of searching I decided to ask a question. I googled on this topic and I have a suggestion that I should delve into the messenger pattern and converters
MainWindow.xaml(View)
<Window x:Class="NotesARK6.View.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:NotesARK6.View"
xmlns:model="clr-namespace:NotesARK6.Model"
xmlns:viewmodel="clr-namespace:NotesARK6.ViewModel"
mc:Ignorable="d"
Title="Notes" Height="450" Width="800"
x:Name="_mainWindow"
WindowStartupLocation="CenterScreen">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="20" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="20"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="10*"/>
<RowDefinition Height="20"/>
</Grid.RowDefinitions>
<DataGrid ItemsSource="{Binding NotesCollection}" SelectedItem="{Binding SelectedNote}" IsReadOnly="True" AutoGenerateColumns="False" x:Name="DataGrid_Notes" Margin="5" Grid.Row="2" Grid.Column="1">
<DataGrid.InputBindings>
<MouseBinding Gesture="LeftDoubleClick" Command="{Binding EditNoteCommand}" CommandParameter="{Binding SelectedNote}" />
</DataGrid.InputBindings>
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Width="1*" Binding="{Binding Name}"/>
<DataGridTextColumn Header="Content" Width="3*" Binding="{Binding Content}"/>
</DataGrid.Columns>
</DataGrid>
<ToolBar Grid.Row="1" Grid.Column="1" Margin="5">
<Button Content="Create" Command="{Binding CreateNewNoteCommand}"/>
<Separator />
<Button Content="Delete" Command="{Binding DeleteNoteCommand}" CommandParameter="{Binding SelectedNote}"/>
<Separator />
<Button Content="Find" Command="{Binding FindNoteCommand}"/>
</ToolBar>
</Grid>
</Window>
FindWindowDialog.xaml(view)
<Window x:Class="NotesARK6.ViewModel.Dialogs.FindWindowDialog"
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:NotesARK6.ViewModel.Dialogs"
mc:Ignorable="d"
Title="Find" Height="250" Width="400"
WindowStartupLocation="CenterScreen"
Topmost="True">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="20"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition Height="35"/>
<RowDefinition Height="60"/>
<RowDefinition Height="50"/>
<RowDefinition Height="90"/>
</Grid.RowDefinitions>
<Grid Grid.Row="1" Grid.Column="1">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<CheckBox IsChecked="{Binding SearchByName}" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="5" Content="Search by name" Grid.Column="0"></CheckBox>
<CheckBox IsChecked="{Binding SearchByContent}" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="5" Content="Search by content" Grid.Column="1"></CheckBox>
</Grid>
<TextBox Text="{Binding SearchString}" Margin="5" Grid.Row="2" Grid.Column="1"/>
<Button Command="{Binding FindNotesCommand}" Margin="5" Content="Find" Grid.Row="3" Grid.Column="1" />
</Grid>
</Window>
FindWindowDialogViewModel.cs
public class FindWindowDialogViewModel : INotifyPropertyChanged
{
private string searchString;
private bool searchByName;
private bool searchByContent;
//Controll Commands
public ControllComands FindNotesCommand { get; private set; }
//Controll Commands
public FindWindowDialogViewModel()
{
FindNotesCommand = new ControllComands(FindNote);
}
public string SearchString
{
get
{
return searchString;
}
set
{
searchString = value;
OnPropertyChanged();
}
}
public bool SearchByName
{
get
{
return searchByName;
}
set
{
searchByName = value;
OnPropertyChanged("SearchByName");
}
}
public bool SearchByContent
{
get
{
return searchByContent;
}
set
{
searchByContent = value;
OnPropertyChanged("SearchByContent");
}
}
public void FindNote()
{
MessageBox.Show(SearchByName.ToString() + " " + SearchByContent.ToString());
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName]string prop = "")
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(prop));
}
}
How can I use the command contained in FindWindowDialogViewModel to hide rows in the DataGrid MainWindowView ?
I would like something like this: (this is pseudocode)
public void FindNote()
{
foreach(var row in MainWindow.DataGrid.Rows)
{
string searchingText = FindNoteDialog.TextBox.Text;
if (!row.Content.Contains(searchingText))
{
row.Visibillity = false;
}
}
}
For this purpose collections provide filtering via their views (see Binding to collections and CollectionView API remarks to learn more).
Filtering using the collection's view has much better performance than hiding rows or removing items from the original collection.
To do so, you must get the ICollectionView of the source collection
Note.cs
class Note
{
public string Summary { get; set; }
public DateTime Timestamp { get; set; }
}
ViewModel.cs
class ViewModel : INotifyPropertyChanged
{
public ObservableCollection<Note> Notes { get; }
public string SearchKey { get; set; }
public ICommand FilterNotesCommand => new RelayCommand(ExecuteFilterNotes);
private void ExecuteFilterCommands(object commandParameter)
{
ICollectionView notesView = CollectionViewSource.GetDefaultView(this.Notes);
notesView.Filter = item => (item as Note).Summary.Contains(this.SearchKey);
}
}
MainWindow.xaml
<Window>
<Window.DataContext>
<ViewModel />
</Window.DataContext>
<StackPanel>
<TextBox Text="{Binding SearchKey}" />
<Button Command="{Binding FilterNotesCommand}" Content="Filter Table" />
<DataGrid ItemsSource="{Binding Notes}" />
</StackPanel>
</Window>
I have a texblock in my .xaml file that I have binded to a property. There are also 2 buttons to ++ and -- the value of that property when they are clicked. The problem is that the binding works only at the start of the application.
When the button is clicked the corresponding command is executed and variable changes its value in the code (so there is no problem with executing the given methods).
However no changes are visible in the UI. I am not sure what might be the cause here, is the UI being somehow blocked? I have always worked using MVVM way and never have had a problem like that with binding.
If more code is needed let me know, didn't want to put a huge wall of code here.
Constructor:
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
Zoom = 60;
ZoomPlusSceneCommand = new RelayCommand(ZoomPlus);
ZoomMinusSceneCommand = new RelayCommand(ZoomMinus);
}
Handling property changed:
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged(string propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
Property itself:
private int zoom;
public int Zoom
{
get { return zoom; }
set { if (zoom != value) { zoom = value; RaisePropertyChanged("Zoom"); } }
}
Commands:
public RelayCommand ZoomPlusSceneCommand { get; set; }
public RelayCommand ZoomMinusSceneCommand { get; set; }
where RelayCommand is an implementation that I use as a template in most of my projects and they've always been working well (at least in MVVM projects)
Methods executed with the usage of commands when a button is clicked:
private void ZoomPlus(object o)
{
Zoom++;
}
private void ZoomMinus(object o)
{
Zoom--;
}
Xaml:
<Window x:Class="Rendering3D.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:Rendering3D"
Loaded="GetSceneSize"
ResizeMode="NoResize"
mc:Ignorable="d"
Title="MainWindow" Height="550" Width="900">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10"/>
<ColumnDefinition x:Name="SceneColumn" Width="*"/>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="40"/>
<ColumnDefinition Width="10"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="10"/>
<RowDefinition x:Name="SceneRow" Height="*"/>
<RowDefinition Height="10"/>
</Grid.RowDefinitions>
<Image x:Name="SceneImage" Grid.Column="1" Grid.Row="1"
PreviewMouseLeftButtonDown="SceneMouseLeftButtonDown"
MouseMove="SceneMouseMove"
MouseWheel="SceneMouseWheel"/>
<Grid Grid.Column="3" Grid.Row="1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="10"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="10"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.Resources>
<Style TargetType="Button">
<Setter Property="Padding" Value="0 5 0 5"/>
</Style>
</Grid.Resources>
<Button Grid.Row="0" Content="+" Command="{Binding ZoomPlusSceneCommand}"/>
<Button Grid.Row="2" Content="-" Command="{Binding ZoomMinusSceneCommand}"/>
<Label Grid.Row="4" Content="Zoom" HorizontalAlignment="Center"/>
<TextBlock Grid.Row="5" Text="{Binding Zoom}" HorizontalAlignment="Center"/>
</Grid>
</Grid>
Example of a mouse event:
private void SceneMouseWheel(object sender, MouseWheelEventArgs e)
{
if (e.Delta > 0)
Zoom++;
else
Zoom--;
return;
}
Assuming the property gets set, the view should be updated provided that your MainWindow class actually implements INotifyPropertyChanged:
public partial class MainWindow : Window, INotifyPropertyChanged
...
Hi everyone,
I am trying to implement MVVM in my application but i am failing to load data.
I have a main page and it works fine, but once I want to navigate to the detail of my Ad and then the detail page is blank. There are my controls so i know that the pages is loaded just my data are missing. I cant seem to figure out where i have made the mistake. I am new to coding so i sometimes tend to make very silly mistakes. I been trying to solve this for past few hours otherwise would not post it over here. Thank you of any opinion.
My HomePage
<Grid Grid.Row="1" Margin="0,25,0,0">
<CollectionView x:Name="ads"
ItemsSource="{Binding AdLogEntries}"
ItemTemplate="{StaticResource HomePageTemplate}"
SelectionMode="Single"
SelectedItem="{Binding SelectedAd, Mode=TwoWay}"
SelectionChanged="CollectionView_SelectionChanged"
Margin="12,0">
</CollectionView>
</Grid>
public partial class HomePage : ContentPage
{
public HomePage()
{
InitializeComponent();
BindingContext = new HomePage ViewModel();
}
async void CollectionView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var selectedAd = (AdLogEntry)e.CurrentSelection.FirstOrDefault();
if (selectedAd != null)
{
await Navigation.PushAsync(new AdDetail(selectedAd));
}
}
}
namespace Baltazar.ViewModel
{
public class HomePageViewModel : BaseViewModel
{
ObservableCollection<AdLogEntry> _adLogEntries;
public ObservableCollection<AdLogEntry> AdLogEntries { get => _adLogEntries; set { _adLogEntries = value; OnPropertyChanged(); } }
public AdLogEntry selectedAd;
public HomePageViewModel()
{
AdLogEntries = new ObservableCollection<AdLogEntry>()
{
new AdLogEntry (){Id = 0, Image = "cat.jpg", Name = "Kocka" , Description = "seda kocka na prodej, mayliva, hrava, spolecenska " ,Price = 120, },
new AdLogEntry (){Id = 1, Image = "cat2.jpg", Name = "Kocka", Description = "seda kocka na prodej, mayliva, hrava, spolecenska " ,Price = 120, },
new AdLogEntry (){Id = 2, Image = "bobtailjpg.jpg", Name = "Kocka",Description = "seda kocka na prodej, mayliva, hrava, spolecenska ", Price = 120, },
};
}
}
}
//Detail
public class AdDetailViewModel : BaseViewModel
{
AdLogEntry _adDetail;
public AdLogEntry AdDetail { get => _adDetail;set { _adDetail = value;OnPropertyChanged(); } }
public AdDetailViewModel(AdLogEntry adDetail)
{
AdDetail = adDetail;
}
}
public partial class AdDetail : ContentPage
{
//private AdLogEntry selectedAd;
public AdDetail(AdLogEntry adDetail)
{
InitializeComponent();
BindingContext = new AdDetailViewModel(adDetail);
}
}
//BaseViewModel
public class BaseViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected BaseViewModel()
{
}
protected virtual void OnPropertyChanged([CallerMemberName]string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="300" />
<RowDefinition Height="40" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ffimageloading:CachedImage
x:Name="HeaderView"
Grid.Row="0"
Grid.RowSpan="2"
Aspect="AspectFill"
Source="{Binding AdLogEntries.Image}"/>
<controls:Parallax Control
x:Name="Parallax"
Grid.Row="0"
Grid.RowSpan="3">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="300" />
<RowDefinition />
</Grid.RowDefinitions>
<yummy:Pancake View
Grid.Row="1"
CornerRadius="24, 24, 0, 0"
BackgroundColor="{StaticResource BackgroundColor}"
Margin="0, 20, 0, 0">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!-- Animal NAME -->
<Label
Grid.Row="0"
Text="{Binding AdLogEntries.Name}"
/>
<!-- QUANTITY -->
<Grid
Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label
Grid.Column="1"
Text="{Binding AdLogEntries.Price, StringFormat='{0:C0}'}"
/>
</Grid>
<!-- ABOUT -->
<Label
Grid.Row="2"
Text="Popis"
/>
<!-- DESCRIPTION -->
<Label
Grid.Row="3"
Text="{Binding AdLogEntries.Description}"
/>
<Grid
Grid.Row="4"
Margin="0, 12">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80"/>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!-- BUY NOW BUTTON -->
<yummy:PancakeView
Grid.Column="1"
HeightRequest="48"
CornerRadius="24, 0, 24, 0"
Background Color="Accent"
Margin="24, 0, 0, 0">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Label
Grid.Column="1"
Text="Buy now"
/>
<Label
Grid.Column="2"
Text=">"
/>
</Grid>
</yummy:Pancake View>
</Grid>
</Grid>
</yummy:Pancake View>
</Grid>
</controls:Parallax Control>
</Grid>
</ContentPage.Content>
Your SelectedItem never changes because you are not trigger OnPropertyChange. You can change your view model logic like this:
private AdLogEntry selectedAd;
public AdLogEntry SelectedAd { get => selectedAd; set { selectedAd = value; OnPropertyChanged("SelectedAd"); } }
public ICommand AdSelectionChangedCommand => new Command(AdSelectionChanged);
private void AdSelectionChanged()
{
OnPropertyChanged("SelectedAd");
Application.Current.MainPage.Navigation.PushModalAsync(new DetailPage(SelectedAd));
}
And in your XAML:
<CollectionView x:Name="ads"
ItemsSource="{Binding AdLogEntries}"
SelectionMode="Single"
SelectionChangedCommand="{Binding AdSelectionChangedCommand}"
SelectedItem="{Binding SelectedAd, Mode=TwoWay}"
Margin="12,0">
Your detail page:
public DetailPage(AdLogEntry detail)
{
this.BindingContext = new AdDetailViewModel(adDetail);
InitializeComponent();
}
In Detail XAML:
<Label Text="{Binding AdDetail.Name}"/>
your BindingContext is AdDetailViewModel
BindingContext = new AdDetailViewModel(adDetail);
and your binding paths are like
<Label Grid.Row="3" Text="{Binding AdLogEntries.Description}"
AdDetailViewModel does not have a AdLogEntries property. It does have a AdDetail, so presumably you should use this as a binding path
<Label Grid.Row="3" Text="{Binding AdDetail.Description}"
The problem is in your detail page XAML. To be precise, the problem is in your XAML Binding Expressions. All the bindings in the detail page has wrong path set. For example, for image control it should be Source="{Binding AdDetail.Image}" instead of Source="{Binding AdLogEntries.Image}". It happens all the time and you catch these kind of errors in the output log when you debug the application.
What I'm trying to do is bind the controls generated by a ItemsControl.ItemTemplate to a new instance of my ContactInterface class that is created whenever I run my query function.
ContactInterface.cs:
class ContactInterface : INotifyPropertyChanged
{
public string Type { get; set; }
private string firstname;
public string FirstName {
get{return this.firstname;}
set {
if (this.firstname != value) {
this.firstname = value;
this.NotifyPropertyChanged("FirstName");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string propName)
{
if (this.PropertyChanged != null)
this.PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
}
SQL.cs
partial class MainWindow
{
private void selectContact(int? contactID)
{
using (ContactsDataContext context = new ContactsDataContext("Data Source=ds;Initial Catalog=db;Integrated Security=True"))
{
Contact contact = context.Contacts.SingleOrDefault(x => x.ContactID == contactID);
Contact spouse = context.Contacts.SingleOrDefault(x => x.ContactID == contact.Spouse);
Property property = context.Properties.SingleOrDefault(x => x.PropertyID == contact.Address);
ContactInterface selectedContact= new ContactInterface();
selectedContact.FirstName = contact.FirstName;
profileGrid.DataContext = selectedContact;
}
}
MainWindow.xaml
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="300" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ItemsControl Name="Profile_Page_Controls">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid Margin="15">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="30" />
<ColumnDefinition Width="100" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="43" />
<RowDefinition Height="43" />
<RowDefinition Height="43" />
<RowDefinition Height="43" />
<RowDefinition Height="43" />
<RowDefinition Height="43" />
<RowDefinition Height="43" />
<RowDefinition Height="43" />
</Grid.RowDefinitions>
</Grid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding TextContent}"/>
<TextBox Height="23" Text="{Binding Path=FirstName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged }"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Grid.Column" Value="{Binding profile_Column}" />
<Setter Property ="Grid.Row" Value="{Binding profile_Row}" />
<Setter Property="Grid.ColumnSpan" Value="{Binding profile_Colspan}" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
<CheckBox Name="profile_SpouseCheck" Grid.Column="1" Margin="0,0,0,0" Checked="profile_SpouseCheck_Checked_1" Unchecked="profile_SpouseCheck_Checked_1"> Spouse</CheckBox>
</Grid>
My plan is to make a new ContactInterface instance every time a user runs the selectContact() function. That new instance will be bound to the generated controls, so when the user makes and saves a change, the textboxes will update that ContactInterface instance and my other functions can grab the data from that ContactInterface to make changes to the database.
Any ideas?
There in my mainwindow.xaml I've got the grid with:
<CustomControl:GridControl ShowCustomGridLines="True" Grid.Column="2" Grid.Row="0">
<local:_13cap/>
</CustomControl:GridControl>
Where 13cap is my custom control:
<UserControl x:Class="TTTP._13cap"
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:CustomControl="clr-namespace:WpfApplication1.CustomControl"
mc:Ignorable="d">
<CustomControl:GridControl ShowCustomGridLines="True">
<Grid.ColumnDefinitions>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Grid.ColumnSpan="3" Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center" Text="ВСЕГО" />
<CustomControl:GridControl ShowCustomGridLines="True" Grid.Column="2" Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Grid.Row="1" Text="П" HorizontalAlignment="Center" VerticalAlignment="Center" />
<TextBlock Grid.Column="1" Grid.Row="1" Text="Ф" HorizontalAlignment="Center" VerticalAlignment="Center" />
<TextBlock Grid.Column="2" Grid.Row="1" Text="%" HorizontalAlignment="Center" VerticalAlignment="Center" />
</CustomControl:GridControl>
</CustomControl:GridControl>
</UserControl>
But I want to call it with only one different text parameter ( Text="ВСЕГО" ) alike I want to call <local:_13cap MyText="CustomText"/> to override "ВСЕГО". How can I create UserControl with such parameter in it?
Implement a DependancyProperty that you can change from code-behind and bind to in XAML.
Code behind:
public class MyUserControl : UserControl, INotifyPropertyChanged
{
//INotifyPropertyChanged implementation
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
//The XAML binding uses this
public static readonly DependencyProperty CaptionProperty =
DependencyProperty.Register("Caption", typeof(string), typeof(MyUserControl),
new PropertyMetadata(string.Empty, OnCaptionPropertyChanged));
//Your code-behind uses this
public string Caption
{
get { return GetValue(CaptionProperty).ToString(); }
set
{
SetValue(CaptionProperty, value);
OnPropertyChanged("Caption");
}
}
Xaml:
<UserControl (...)>
<Grid>
<Label x:Name="labCaption" Content="{Binding Caption}"/>
</Grid>
</UserControl>
There are lots of other questions here about this and lots of good articles and tutorial on google that explain it all better then I could.