I have
<Window x:Class="Repo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:Repo="clr-namespace:Repo" Title="Window1" Height="300" Width="300">
<Grid>
<Button Click="SaVeEverythingInDatabase></Button>
<Repo:UserControlTasks/>
</Grid>
</Window>
public class UserControlTasks:userControl
public partial class UserControlTasks: UserControl
{
public UserControlTasks()
{
InitializeComponent();
LoadView();
}
private void LoadView()
{
this.lbTasks.ItemsSource = new TaskModelView();//collectionOfTasks
}
How to get collection from lbTasks in UserControlTasks when I click button on MainWindow?
I must add that I this collection is a part of instances of class Student which is datacontext of MainWindow.
Create TaskModelView in MainWindow class and assign it to Button control and UserControlTasks control. You will need to add a dependecy property for this to UserControlTasks.
Related
I have two xaml toggles in separate files that I want to update simultaneously (if one is switched on the other should be too (and vice versa). My first switch in xaml is:
<Switch Grid.Column="1" x:Name="toggleSwitch1" IsToggled="true" Toggled="OnToggled"/>
Using C# how can I return a boolean value of this switch so that I can update another switch simultaneously? Then once retrieving the value, how can I update the xaml of the toggle status for the other switch?
Your Switch control means, as I can understand, that you using UWP, but I'm not sure.
Anyway, the idea is to bind both controls IsToggled properties to same property of some ViewModel:
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace MyWPFApp
{
public class ControlsViewModel : INotifyPropertyChanged
{
private bool switchToggled;
public bool SwitchToggled
{
get => switchToggled;
set
{
switchToggled = value;
OnPropertyChanged(nameof(SwitchToggled));
}
}
public ControlsViewModel() { }
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName]string propertyName = "") =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Then in XAML of both Windows set bindings to Switch control (in my example - CheckBox control):
<!-- Window 1 -->
<Window x:Class="MyWPFApp.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:MyWPFApp"
mc:Ignorable="d"
Title="Window 1" Height="100" Width="300">
<Grid>
<CheckBox Content="Window1 CheckBox"
IsChecked="{Binding SwitchToggled}"/>
<!-- Replace IsChecked to IsToggled property -->
</Grid>
</Window>
<!-- Window 2 -->
<Window x:Class="MyWPFApp.Window2"
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:MyWPFApp"
mc:Ignorable="d"
Title="Window 2" Height="100" Width="300">
<Grid>
<CheckBox Content="Window2 CheckBox"
IsChecked="{Binding SwitchToggled}"/>
<!-- Replace IsChecked to IsToggled property -->
</Grid>
</Window>
Code-behind of both Windows in example is same:
using System.Windows;
namespace MyWPFApp
{
public partial class Window1 : Window // or public partial class Window2
{
public Window1(ControlsViewModel cvm) // or public Window2
{
InitializeComponent();
DataContext = cvm;
}
}
}
And when calling that example Windows to show from Main one, you creating ControlsViewModel instance and pass it to both:
using System.Windows;
namespace MyWPFApp
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var cvm = new ControlsViewModel();
new Window1(cvm).Show();
new Window2(cvm).Show();
}
}
}
So checking/unchecking (toggle/untoggle) one of them will affect another and vice versa. Also, you can change SwitchToggled from code somewhere, which would affect both controls too.
Please note, that this is just example to try explain the idea. More MVVM pattern explanations and examples you can find at MSDN.
I have a set of UserControls in a library, but because the library is in a different namespace than the MainWindow, I don't seem to be able to get one UserControl to retrieve List<features> from MainWindow.
I suspect this is because UserControl does not know of MainWindow, and it's not meant to, as it is in a DLL library. As the UserControl is in a DLL, it should be agnostic to namespaces, but still be able to get what it needs.
So below I put some XAML and relative C# code-behind where you can see on the UserControls ListBox, I'm trying to retrieve the features list from MainWindow.
<UserControl x:Class="FlatControls.MyListBox"
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:FlatControls"
mc:Ignorable="d"
d:DesignHeight="34" d:DesignWidth="100" MaxHeight="34" MaxWidth="100" x:Name="root">
<ListBox x:Name="listBox">
</UserControl>
public MyListBox()
{
InitializeComponent();
listBox.Items = ???????????
}
<Window x:Class="MyApp.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:WpfApp4"
xmlns:FC="clr-namespace:FlatControls;assembly=FlatControls"
mc:Ignorable="d"
Title="MainWindow" Height="1000" Width="1900" WindowState="Maximized" RenderOptions.BitmapScalingMode="Fant">
<Grid>
xyz
</Grid>
<Window>
namespace MyApp
{
public List<string> features = new List<string>();
public MainWindow()
{
InitializeComponent();
features.Add("Concave");
features.Add("Convex");
}
}
Any help would be greatly appreciated, whether it's via Binding, or code-behind :D
The ListBox in your custom UserControl has to bind its ItemsSource from somewhere. You should create an ItemsSource dependency property in your MyListBox to enable binding a collection from outside.
public partial class MyListBox : UserControl
{
public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register(
nameof(ItemsSource), typeof(IEnumerable), typeof(MyListBox), new PropertyMetadata());
public IEnumerable ItemsSource
{
get => (IEnumerable)GetValue(ItemsSourceProperty);
set => SetValue(ItemsSourceProperty, value);
}
public MyListBox()
{
InitializeComponent();
}
}
In the markup for the MyListBox user control, bind to this property using a RelativeSource binding.
<UserControl x:Class="FlatControls.MyListBox"
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:FlatControls"
mc:Ignorable="d"
d:DesignHeight="34" d:DesignWidth="100" MaxHeight="34" MaxWidth="100" x:Name="root">
<ListBox x:Name="listBox" ItemsSource="{Binding ItemsSource, RelativeSource={RelativeSource AncestorType={x:Type local:MyListBox}}}"/>
</UserControl>
Now, in your MainWindow use the control (you already added the corresponding XML namespace).
<Window x:Class="MyApp.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:WpfApp4"
xmlns:FC="clr-namespace:FlatControls;assembly=FlatControls"
mc:Ignorable="d"
Title="MainWindow" Height="1000" Width="1900" WindowState="Maximized" RenderOptions.BitmapScalingMode="Fant">
<Grid>
<FC:MyListBox x:Name="MyListBox"/>
</Grid>
<Window>
Finally, assign the ItemsSource property of the MyListBox control with the features collection.
public MainWindow()
{
InitializeComponent();
features.Add("Concave");
features.Add("Convex");
MyListBox.ItemsSource = Features;
}
Alternatively, expose a property Features for your items and bind it in XAML.
public List<string> Features { get; }
<FC:MyListBox ItemsSource="{Binding Features}"/>
As #thatguy said, you can use his way to do.
Of course, if you like to write code in view.cs, you can use "FieldModifier" word to decorade you listbox in your MyListBox:
<ListBox x:Name="listBox" x:FieldModifier="public" />
And in your MainWindow, you can get the listbox instance, of cource, you can set its itemsource like this:
public MainWindow()
{
InitializeComponent();
this.userControl.listBox.ItemsSource = new List<string>() { "11","22","33"};
}
This question already has answers here:
Issue with DependencyProperty binding
(3 answers)
How to correctly bind to a dependency property of a usercontrol in a MVVM framework
(4 answers)
Closed 4 years ago.
I am attempting to get to grips with DataBinding, and I have just started to introduce UserControls into the mix, but it appears I cannot even get the most basic example working.
I have a MainWindow that contains a property (Subtitle) along with an instance of a UserControl. A property of the UserControl (LabelContent) is bound to the Subtitle property. The expected result is that changing the Subtitle property of MainWindow will update the LabelContent property of the UserControl, which is bound to the actual Content property of a Label within the UserControl:
I have MainWindow.xaml:
<Window x:Class="WpfApp1.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:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<local:UserControlSample LabelContent="{Binding Subtitle}"/>
With the following code behind (MainWindow.cs):
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = this;
Subtitle = "Test";
}
public String Subtitle
{
get;
set;
}
}
UserControlSample.xaml:
<UserControl x:Class="WpfApp1.UserControlSample"
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:WpfApp1"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Label Content="{Binding Path=LabelContent}"/>
UserControl.cs:
public partial class UserControlSample : UserControl
{
public static DependencyProperty LabelContentProperty = DependencyProperty.Register("LabelContent", typeof(String), typeof(UserControlSample));
public UserControlSample()
{
InitializeComponent();
DataContext = this;
}
public String LabelContent
{
get { return (String)GetValue(LabelContentProperty); }
set { SetValue(LabelContentProperty, value); }
}
}
I believe it is something to do with DataContexts however I do not understand them too well as yet. If I change UserControl to the following, then I achieve the expected results. However this does not explain the reasons why the original code fails:
UserControlSample.xaml
<Label Content="{Binding Path=Subtitle}"/>
UserControl.cs
public UserControlSample()
{
InitializeComponent();
}
You would need changes at two places,
First in Xaml, you need to set the source object of the Binding to the UserControl
<Label Content="{Binding Path=LabelContent,RelativeSource={RelativeSource AncestorType=UserControl}}" />
Secondly,
public UserControl1()
{
InitializeComponent();
}
That should allow you to bind the User Control correctly
MainWindow UI
<Window x:Class="PrismSanity.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:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<TextBlock Text="{Binding MyName}"></TextBlock>
</Grid>
</Window>
MainWindowViewModel
public class MainWindowViewModel : BindableBase
{
private string _MyName = "John";
public string MyName
{
get { return _MyName = "John"; }
set { SetProperty(ref _MyName, value); }
}
}
I installed SNOOP to see what was happening, but the VM is not being Linked to the View. If I do the same thing with a second view, and use
<ContectContainer>
<views:ViewA/>
</ContentContainer>
in the Mainwindow
Then I get the ViewA and ViewAViewModel to link fine.
Thanks for looking.
Prism supports only UserControl class not Window class. AutoWireViewModel wokrs only with UserControl class.
I have the same problem I resolve this binding the context in code behind - partial using Unity. Something like that:
public partial class ShellView : Window
{
public ShellView(ShellViewModel viewModel)
{
this.InitializeComponent();
// Set the ViewModel as this View's data context.
this.DataContext = viewModel;
}
When app create the ShellView (it is your PrismSanity.MainWindow) unity inject the viewModel (ShellViewModel )
It is little technology debt.
I want add a list in UserControl and its values are coming from Json. So how can I bind those values into UserControl from another page and also I want to add a SelectionChanged Event for it.
The scenario is as below:
I have a xaml page containing an image plugin(image). On clicking on Image I want to open UserControl containing list values( for e.g. Take Photo, Select from Library,Record Video and Cancel). Once the user selects the item based on that different method are called.
I was achieving the same approach using CustomMessageBox in Windows Phone 8 but that is not available and I may need to use UserControl to achieve this.
Please guide me for this.
Update
What I have tried so far.
UserControl.Xaml
<UserControl
x:Class="TestApp.Resources.CameraPluginOptions"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:MyCouncilServices.Resources"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400">
<Grid>
<ListView x:Name="CameraPlugin"
ItemContainerStyle="{StaticResource GenericListViewContainerStyle}"
ItemTemplate="{StaticResource EvidenceListItemTemplate}"
ItemSource="{Binding ItemSource}"
/>
</Grid>
UserControl.xaml.cs
public sealed partial class CameraPluginOptions : UserControl
{
public event EventHandler SelectionChanged;
public List<SUBPARAM> ItemSource
{
get { return (List<SUBPARAM>)GetValue(evidenceItemSourceproperty); }
set { SetValue(evidenceItemSourceproperty, value); }
}
public static readonly DependencyProperty evidenceItemSourceproperty =
DependencyProperty.Register("ItemSource", typeof(List<SUBPARAM>),
typeof(CameraPluginOptions), new PropertyMetadata(0));
public SUBPARAM SelectedOption
{
get { return (SUBPARAM)GetValue(selectedoptionproperty);}
set { SetValue(selectedoptionproperty,value); }
}
public static readonly DependencyProperty selectedoptionproperty =
DependencyProperty.Register("SelectedOption", typeof(SUBPARAM),
typeof(CameraPluginOptions), new PropertyMetadata(0));
private void PluginSelectionChanged(object sender,SelectionChangedEventArgs e)
{
if(SelectionChanged !=null)
SelectionChanged(this,new EventArgs());
}
public CameraPluginOptions()
{
this.InitializeComponent();
}
}
The Page from which I want to use UserControl
TestUserControlPage.xaml.cs
PluginControl.DataContext = new EvidenceSource(){ItemSource=MCSManager.Instance.currentClientParams.EVIDENCE_MENU.SUB_PARAMS};
PluginControl.SelectionChanged += MediaListSelectionChanged;
TestUSerControl.xaml where I am using UserControl
<Grid x:Name="imagePlugin"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Height="400"
Width="600"
Visibility="Collapsed"
xmlns:local="using:TestApp.Resources">
<local:CameraPluginOptions x:Name="PluginControl"
/>
What I actually want to do is bind the list which I get from Json into UserControl ListBox.Itemsource and then I want to have SelectionChanged Event on same page from which UserControl is called. When a user selects an Item particular action should take place.