Click here to Skip to main content
15,849,678 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
hi, i have a Mainwindow.Xaml(wpf form) and 2x UserControl(EventPage.xaml and dashboard.xaml) inside this MainWindow.xaml i have a textbox and a button and i using this code to switch between my forms(EventPage.Xaml and Dashboard.Xaml) inside this Grid:
<Grid x:Name="myContainer">
                        <Local:EventPage x:Name="eventpage" Visibility="Collapsed"></Local:EventPage>
                        <Local:Dashboard x:Name="dashboard" Visibility="Collapsed"></Local:Dashboard>       
                    </Grid>

now i wanna pass my textbox.text to my Dashboard.Xaml with this code:

public partial class MainWindow : Window
   {
       public string Searchtext;


       public MainWindow()
       {
           InitializeComponent();


       }
private void SearchBtn_Click(object sender, RoutedEventArgs e)
       {
           Searchtext = txtSearch.Text;
           Dashboard dashPage = new Dashboard(Searchtext);
       }

and in my usercontrol.xaml(Dashboard.Xaml) i have this code to recive my Searchtext :

public partial class Dashboard : UserControl
   {
       string searchtxt;

       public Dashboard(string searchtext)
       {
           InitializeComponent();

           searchtxt = searchtext;
       }

but i getting this error from Mainwindows.xaml in this line:
<Local:Dashboard x:Name="dashboard" Visibility="Collapsed"></Local:Dashboard>

first Error: Type 'Dashboard' is not usable as an object elemenct becuase it is not public or does not define a public parameterless constructor or a type converter.
second Error: the type 'Dashboard' cannot have a Name attribute.Value types without a default constructor can be used as items within a ResourceDictionary.

What I have tried:

i tried make my
string Searchtext
as
Public string Searchtext
and i set
x:FieldModifier="public"
into my DataGrid insid my Dashboard.xaml but none of them did't worked :(
Posted
Updated 8-Feb-23 12:04pm
v2
Comments
Gerry Schmitz 8-Feb-23 14:50pm    
Control "names" are only visible to the containing class; if you want to reference them as a "public property:, you need to add a public reference; e.g. public Dashboard Dashboard => this.dashboard.

(Use a "naming convention" for control names so you can keep then separate from "other names")
Max Speed 2022 8-Feb-23 15:14pm    
Hi,i think it's not about name of controls,when i trying to pass an string value to another form,s that's happen :(

1 solution

Why are you trying to pass a string in the constructor of the user control? This will only work if you are manually initializing the UserControl and adding to the main window - a one-shot deal.

A UserControl is just a class with UI functionality included, so it has the same rules of usage.

If you want to pass a value to a UserControl, add a public property or Method. Then you can pass values from the MainWindow to the UserControl - at any time for the life of the UserControl.

Here is a little demo for you.

NOTE: This is not how I would normally do this. However, I feel that this is as simple as I can make it for you.

The MainWindow has two UserControls:
* SearchWidget holds the search input functionality
* DashboardWidget Takes the Search and applies it.

The two controls communicate via the MainWindow.

1. DashboardWidget UserControl:
XML
<UserControl x:Class="WpfControlBasicsDemo.DashboardWidget"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid>
            <TextBlock x:Name="SearchText"
                       FontSize="32"
                       HorizontalAlignment="Center"
                       VerticalAlignment="Center"/>
    </Grid>
</UserControl>

and the code-behind:
C#
public partial class DashboardWidget : UserControl
{
    public DashboardWidget()
    {
        InitializeComponent();
    }

    public void DoSearch(string searchText)
    {
        // do a search....
        SearchText.Text = searchText;
    }
}

I have exposed a method to take the search text and do something with it.

2. SearchWidget UserControl:
XML
<UserControl x:Class="WpfControlBasicsDemo.SearchWidget"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid Margin="10">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition />
                <ColumnDefinition Width="Auto" />
            </Grid.ColumnDefinitions>
        <Label Content="Search:"
               FontWeight="Bold"
               Margin="0 0 10 0"/>
        <TextBox Grid.Column="1"
                 x:Name="txtSearch" />
        <Button Grid.Column="2"
                Margin="10 0 0 0"
                Content="Search"
                Click="ButtonBase_OnClick"/>
    </Grid>
</UserControl>

and the code-behind:
C#
public partial class SearchWidget : UserControl, INotifyPropertyChanged
{
    private string searchText;

    public SearchWidget()
    {
        InitializeComponent();
    }

    private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
    {
        SearchText = txtSearch.Text;
    }

    public string SearchText
    {
        get => searchText;
        set
        {
            if (value == searchText) return;
            searchText = value;
            OnPropertyChanged();
        }
    }

    public event PropertyChangedEventHandler? PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

Here I do two things:
1. When the button is pressed, I set the public property
2. The public property fires an OnPropertyChanged event.

3. MainWindow
This will host the two UserControls and pass the search text from one to the other:
XML
<Window x:Class="WpfControlBasicsDemo.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:WpfControlBasicsDemo"
        mc:Ignorable="d" Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition/>
        </Grid.RowDefinitions>

        <local:SearchWidget x:Name="SearchWidget"/>
        <local:DashboardWidget x:Name="DashboardWidget" Grid.Row="1"/>
    </Grid>
</Window>

and the code-behind:
C#
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        SearchWidget.PropertyChanged += SearchWidget_PropertyChanged;
    }

    private void SearchWidget_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        DashboardWidget.DoSearch(SearchWidget.SearchText);
    }
}

I listen for the PropertyChanged event from the SearchWidget UserControl and pass the text to the DashboardWidget UserControl via the public method DoSearch.
 
Share this answer
 
Comments
Max Speed 2022 8-Feb-23 18:08pm    
@Graeme_Grant bro I was very confused, what's [question mark] in OnPropertyChanged?feature 'nullable refernce types' sis not avilable in c#
i won't a host between to usercontrol, i just wanna pass a string from mainwindow to a usercontrol :(
thank your for attention bro <3
Graeme_Grant 8-Feb-23 18:41pm    
Yes, Nullable. You do not need to use the '?', you can instead use:
if (PropertyChanged != null)
{
    PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
}


The purpose of the demo code is to show you 2 methods:
1. Using a Property
2. Using a method

I suspect what you need is the second - pass by method. Look at the DashboardWidget UserControl and how it is used from the MainWindow code.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900