Why Only usercontrol can't use binding while others can use it? - c#

I have a question about WPF. There are two component.
1. MainWindow
2. ClothesController: UserControl
MainWindow makes a instance of class 'Shoes' as 'shoes1' with property value 'Size' = 170. This instance is attached to the MainWindow as 'DataContext' and can be easily referenced by Label control 'label_1'. So, label_1 displays 170. Good as expected.
And I made one user control; ClothesController
It has a DependencyProperty 'Value' and bound to UserControl. And a label control refers to this value using same method as 'MainWindow'. The default value is zero.
With this control, I made two instances of 'ClothesController'.
Using exposed DP 'Value', I assigned a value to one instance as binding and for another one, I just assigned an integer directly inside XAML.
The results are
controller_1 is 0; default of DP
controller_2 is 180; As expected
label_1 is 170; As expected
And I can't understand this. Am I missing something?
I'm new to WPF so what I thought is that whatever the type of control is, if it has a modifiable property, then whatever the input is, if the type is matched with that of property, it should be referenced.
Here're the full code. From MainWindow to Usercontrol
++MainWindow
<Window x:Class="FieldUserControl_test.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:FieldUserControl_test"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<local:ClothesController Name = "controller_1" VerticalAlignment="Center" Grid.Row="0" Value="{Binding Path=Size}" Label="Size"/>
<local:ClothesController Name = "controller_2" VerticalAlignment="Center" Grid.Row="1" Value="{Binding Path=Height, ElementName=LayoutRoot}" Label="Height"/>
<Label Name = "label_1" Grid.Row="2" Content="{Binding Path=Size}"/>
</Grid>
</Window>
++cs for MainWindow
namespace FieldUserControl_test
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Shoes shoes1 = new Shoes() { Size = 170, Height = 200 };
LayoutRoot.DataContext = shoes1;
}
}
public class Clothes
{
public int Size { set; get; }
public int Height { set; get; }
}
public class Shoes : Clothes
{
}
}
++UserControl; ClothesController
<UserControl x:Class="FieldUserControl_test.ClothesController"
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:FieldUserControl_test"
mc:Ignorable="d"
d:DesignHeight="30" d:DesignWidth="100">
<Grid Name="GridRoot" Background="AliceBlue">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Content="{Binding Path=Label}" Grid.Row="0" Grid.Column="0" VerticalAlignment="Center"/>
<TextBox Name="Tb_shoes_size" Text="{Binding Path=Value}" VerticalAlignment="Center" Grid.Row="0" Grid.Column="1"/>
</Grid>
</UserControl>
++cs for UserControl
namespace FieldUserControl_test
{
/// <summary>
/// Interaction logic for ClothesController.xaml
/// </summary>
public partial class ClothesController : UserControl
{
public ClothesController()
{
InitializeComponent();
GridRoot.DataContext = this;
//or
this.DataContext = this;
}
public string Label
{
get { return (string)GetValue(LabelProperty); }
set { SetValue(LabelProperty, value); }
}
public int Value
{
get { return (int)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
public static readonly DependencyProperty LabelProperty = DependencyProperty.Register("Label", typeof(string), typeof(ClothesController), new PropertyMetadata(""));
public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(int), typeof(ClothesController), new PropertyMetadata(0));
}
}

Related

Data Binding to User Control Error Data.Binding cannot be converted to System.String

I'm new to WPF and I'm having trouble binding text to a user control I made. It's a simple control, it's just basically a button with text and a image that I want to reuse in several Views.
Here is my User Control's .cs
public partial class MenuItemUserControl : UserControl
{
public string TextToDisplay { get; set; }
public MenuItemUserControl()
{
InitializeComponent();
DataContext = this;
}
}
Here is my User Control's xaml
<UserControl x:Class="Class.Controls.MenuItemUserControl"
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:Class.Controls"
mc:Ignorable="d"
d:DesignHeight="83.33" d:DesignWidth="512">
<Grid>
<Button Style="{StaticResource MenuItemStyle}" Height="Auto" Width="Auto">
<DockPanel LastChildFill="True" Width="512" Height="83.33" HorizontalAlignment="Center" VerticalAlignment="Center">
<Image Source="/Resources/MenuArrow.png" Stretch="None" HorizontalAlignment="Left" VerticalAlignment="Center" DockPanel.Dock="Left"/>
<TextBlock d:Text="sample" Text="{Binding TextToDisplay, Mode=OneWay}" HorizontalAlignment="Left" VerticalAlignment="Center" FontSize="{StaticResource MenuItems}"/>
</DockPanel>
</Button>
</Grid>
</UserControl>
Here is my View xaml
<Page x:Class="Class.Views.MenuOperate"
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:uc="clr-namespace:Class.Controls"
xmlns:local="clr-namespace:Class.Views"
xmlns:properties="clr-namespace:Class.Properties"
xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls" xmlns:viewmodels="clr-namespace:Class.ViewModels" d:DataContext="{d:DesignInstance Type=viewmodels:MenuOperateViewModel}"
mc:Ignorable="d"
d:DesignHeight="500" d:DesignWidth="1024"
Title="MenuOperate">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="83.33"/>
<RowDefinition Height="83.33"/>
<RowDefinition Height="83.33"/>
<RowDefinition Height="83.33"/>
<RowDefinition Height="83.33"/>
<RowDefinition Height="83.33"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="512"/>
<ColumnDefinition Width="512"/>
</Grid.ColumnDefinitions>
<uc:MenuItemUserControl TextToDisplay="{Binding StartStop, Mode=TwoWay}" Grid.Row="0" Grid.Column="0"/>
</Grid>
</Page>
Here is my View Model .cs
namespace Class.ViewModels
{
public class MenuOperateViewModel : ObservableObject
{
private string? _StartStop;
public MenuOperateViewModel()
{
StartStop = Properties.Resources.MenuOperateStart;
}
public string? StartStop
{
get => _StartStop;
set => SetProperty(ref _StartStop, value);
}
}
}
This is the error I get in my View Xaml:
Object of Type 'System.Windows.Data.Binding' cannot be converted to type 'System.String'.
There are two things that prevent that the expression
TextToDisplay="{Binding StartStop}"
works.
The target property of the Binding, i.e. TextToDisplay must be a dependency property.
You must not explicity set the UserControl's DataContext. The Binding will resolve the source property path relative to the current DataContext, i.e. with DataContext = this; in the control's constructor, it expects the source property StartStop on the UserControl, which is obviously wrong.
For details, see Data binding overview
Your code should look like this:
public partial class MenuItemUserControl : UserControl
{
public static readonly DependencyProperty TextToDisplayProperty =
DependencyProperty.Register(
nameof(TextToDisplay),
typeof(string),
typeof(MenuItemUserControl));
public string TextToDisplay
{
get { return (string)GetValue(TextToDisplayProperty); }
set { SetValue(TextToDisplayProperty, value); }
}
public MenuItemUserControl()
{
InitializeComponent();
}
}
The Binding in the UserControl's XAML would then use a RelativeSource Binding.
<TextBlock Text="{Binding TextToDisplay,
RelativeSource={RelativeSource AncestorType=UserControl}}" />

Universal App XAML binding not working on UserControl when inside another UserControl

I'm currently working on a Windows Universal App. I'm still quite new to XAML in general but have had some experience with it.
The issue I'm having is around binding inside a UserControl. I've looked around and can't find an answer to my specific issue.
I have a XAML page that is linked to a ViewModel, this all works fine. Then on that page I'm using a UserControl that is basically just a panel with a header that contains some content. In the content of that panel I have another UserControl that basically just consists of a Label and TextBox.
When I bind things from my ViewModel to the ContentPanel UserControl everything works fine, it picks up my ViewModel context and binds correctly.
However, When I try to bind to the LabelledTextbox UserControl that is contained withing the ContentPanel the binding fails because it is just looking for the property that is on the ViewModel on the ContentPanel instead.
See below for the code I have
Page.xaml
<!--Page.xaml-->
<cc:ContentPanel PanelHeading="LEFT FOOT: Measurements" PanelHeadingBackground="{StaticResource OPCare.PanelHeader}">
<StackPanel>
<cc:LabelledTextbox LabelText="Malleoli Width" Text="test" />
<cc:LabelledTextbox LabelText="Met Head Width" />
</StackPanel>
</cc:ContentPanel>
ContentPanel.xaml
<!--ContentPanel UserControl-->
<UserControl
x:Class="OrthoticTabletApp.Controls.ContentPanel"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:OrthoticTabletApp.Controls"
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"
x:Name="Parent">
<Grid DataContext="{Binding ElementName=Parent}">
<Grid.RowDefinitions>
<RowDefinition Height="50" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid Padding="10" Grid.Column="0" Grid.Row="0" Height="50" Background="{Binding Path=PanelHeadingBackground}">
<TextBlock Height="30" LineHeight="30" Text="{Binding Path=PanelHeading}" />
</Grid>
<Grid Padding="10" Grid.Column="0" Grid.Row="1" Background="White">
<ContentPresenter Content="{Binding Path=PanelBody}" />
</Grid>
</Grid>
</UserControl>
ContentPanel.xaml.cs
[ContentProperty(Name = "PanelBody")]
public sealed partial class ContentPanel : UserControl
{
public static readonly DependencyProperty PanelHeadingProperty = DependencyProperty.Register("PanelHeading", typeof(string), typeof(ContentPanel), new PropertyMetadata(""));
public string PanelHeading
{
get
{
return (string)GetValue(PanelHeadingProperty);
}
set
{
SetValue(PanelHeadingProperty, value);
}
}
public static readonly DependencyProperty PanelBodyProperty = DependencyProperty.Register("PanelBody", typeof(object), typeof(ContentPanel), new PropertyMetadata(null));
public object PanelBody
{
get
{
return (object)GetValue(PanelBodyProperty);
}
set
{
SetValue(PanelBodyProperty, value);
}
}
public Brush PanelHeadingBackground
{
get { return (Brush)GetValue(PanelHeadingBackgroundProperty); }
set { SetValue(PanelHeadingBackgroundProperty, value); }
}
public static readonly DependencyProperty PanelHeadingBackgroundProperty =
DependencyProperty.Register("PanelHeadingBackground", typeof(Brush), typeof(ContentPanel), new PropertyMetadata(null));
public ContentPanel()
{
this.InitializeComponent();
}
}
LabelledTextbox.xaml
<UserControl
x:Class="OrthoticTabletApp.Controls.LabelledTextbox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:OrthoticTabletApp.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="50"
d:DesignWidth="400"
x:Name="Parent">
<Grid DataContext="{Binding ElementName=Parent}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="300" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid Grid.Column="0" Padding="10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="15" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding Path=LabelText}" />
</Grid>
<Grid Grid.Column="1" Padding="10">
<TextBox Text="{Binding Path=Text}" />
</Grid>
</Grid>
</UserControl>
LabelledTextbox.xaml.cs
public sealed partial class LabelledTextbox : UserControl
{
public string LabelText
{
get { return (string)GetValue(LabelTextProperty); }
set { SetValue(LabelTextProperty, value); }
}
// Using a DependencyProperty as the backing store for LabelText. This enables animation, styling, binding, etc...
public static readonly DependencyProperty LabelTextProperty =
DependencyProperty.Register("LabelText", typeof(string), typeof(LabelledTextbox), new PropertyMetadata(null));
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
// Using a DependencyProperty as the backing store for Text. This enables animation, styling, binding, etc...
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text", typeof(string), typeof(LabelledTextbox), new PropertyMetadata(null));
public LabelledTextbox()
{
this.InitializeComponent();
}
}
However, When I try to bind to the LabelledTextbox UserControl that is contained withing the ContentPanel the binding fails because it is just looking for the property that is on the ViewModel on the ContentPanel instead.
If I correctly understood what you've done, some properties of your ContentPanel are bound to the data model in the page's viewmodel, and properties of your LabelledTextbox are bound to the data model in other viewmodel?
If so, you can specify the DataContext for LabelledTextbox for StackPanel which is inside the ContentPanel, just for example like this:
<cc:ContentPanel PanelHeading="{x:Bind Heading}" PanelHeadingBackground="Azure">
<StackPanel>
<StackPanel.DataContext>
<local:LabelledTextboxViewModel x:Name="VM" />
</StackPanel.DataContext>
<cc:LabelledTextbox LabelText="{x:Bind VM.Lable1}" Text="test" />
<cc:LabelledTextbox LabelText="{x:Bind VM.Lable2}" />
</StackPanel>
</local:ContentPanel>
In your page's viewmodel, you can make the data model for ContentPanel and initialize the data for example like this:
public BlankPage3ViewModel()
{
Heading = "LEFT FOOT: Measurements";
}
public string Heading { get; set; }
In the LabelledTextboxViewModel you can code for example like this:
public class LabelledTextboxViewModel
{
public LabelledTextboxViewModel()
{
Lable1 = "Malleoli Width";
Lable2 = "Met Head Width";
}
public string Lable1 { get; set; }
public string Lable2 { get; set; }
}
Usually when we follow the MVVM pattern to develop a project, the data model should not be included inside of the viewmodel, I'm here just for clear and easy delivery, the key point is that you can specify different DataContext for different controls in the same page.

UWP inherit from my Usercontrol

I am trying to create a ModalPage class, it run's well but I want to create 4 subclass to specialize my ModalPage.
My ModalPage inherit from UserControl (XAML + C#). On my sub-classes which inherit from my ModalPage, I must parameterize a specific contents and titles.
I suppose, the best way is to do like the ContentDialog class, have a c# class whith ContentDialog1 : ContentDialog and a XAML page with:
<ContentDialog>
<Grid>
</Grid>
</ContentDialog>
But I can't inherit from my UserControl, because it uses XAML. Should I create a custom control (inherit from Control) instead of a UserControl?
If I expose dependency property to set the value of content in my userControl, the content can be another UserControl?
Yeah, we can use ContentPresenter to implement this. Following is a simple sample:
In XAML:
<UserControl x:Class="UWP.ModalPage"
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:local="using:UWP"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
d:DesignHeight="300"
d:DesignWidth="400"
mc:Ignorable="d">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ContentPresenter x:Name="Title"
HorizontalAlignment="Center"
HorizontalContentAlignment="Center"
Content="{x:Bind ModalTitle}" />
<ContentPresenter x:Name="Content" Grid.Row="1" Content="{x:Bind ModalContent}" />
</Grid>
</UserControl>
In code-behind:
public sealed partial class ModalPage : UserControl
{
public ModalPage()
{
this.InitializeComponent();
}
public static readonly DependencyProperty ModalTitleProperty = DependencyProperty.Register("ModalTitle", typeof(object), typeof(ModalPage), new PropertyMetadata(null));
public object ModalTitle
{
get { return GetValue(ModalTitleProperty); }
set { SetValue(ModalTitleProperty, value); }
}
public static readonly DependencyProperty ModalContentProperty = DependencyProperty.Register("ModalContent", typeof(object), typeof(ModalPage), new PropertyMetadata(null));
public object ModalContent
{
get { return GetValue(ModalContentProperty); }
set { SetValue(ModalContentProperty, value); }
}
}
Then we can use this ModalPage in pages like:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<local:ModalPage ModalTitle="TITLE">
<local:ModalPage.ModalContent>
<local:MyUserControl />
</local:ModalPage.ModalContent>
</local:ModalPage>
</Grid>

WPF TextBlock not updating when using DependencyProperties

The TextBlock displays the default property metadata, but doesn't update when the DependencyProperty changes.
It looks like the view isn't updating, because reading the dependency property after assigning a new value returns the new value.
Here's the code, thanks in advance:
Data.cs:
using System.Windows;
namespace RMS.Kernel
{
public class Data : DependencyObject
{
private delegate void ObjectDelegate(object obj);
public static readonly DependencyProperty MessageProperty =
DependencyProperty.Register("Message", typeof(string), typeof(Data), new PropertyMetadata("start text"));
private string message
{
get { return (string)GetValue(MessageProperty); }
set { SetValue(MessageProperty, value); }
}
public Data() { }
//singleton, make every method accesible anywhere. Only one gui object exists on runtime...
private static Data shared;
public static Data getShared()
{
if (shared == null)
{
shared = new Data();
}
return shared;
}
public void setProperties(string message)
{
this.message = message;
}
}
}
XAML:
<local:CustomWindow x:Class="RMS.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:RMS"
xmlns:control="clr-namespace:RMS.Controls"
xmlns:kernel="clr-namespace:RMS.Kernel"
Title="MainWindow" Height="750" Width="1200">
<Window.DataContext>
<kernel:Data/>
</Window.DataContext>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<control:CustomToolBar x:Name="customToolBar" VerticalAlignment="Top" Grid.Row="0"/>
<TextBlock Text="{Binding Path=Message, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Foreground="White" FontSize="12pt" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Row="1"/>
<control:CustomStatusBar x:Name="CustomStatusBar" VerticalAlignment="Bottom" Grid.Row="2"/>
</Grid>
</local:CustomWindow>

Execute Method in User Control MVVM

I am working on my first MVVM application and am having trouble getting it to work properly.
In my main window, I have a button that executes a SQL command that returns a custom data table type object.
The window also contains a user control that consists of a some column headers and a windows forms hosted DataGridView. I need to somehow tell the user control to execute a method that passes the data to the DataGridView so it can update it's values.
I tried creating a dependency property on my WPF Grid control that is bound to the data of my viewmodel, but it is not updating properly.
How can I get this to work?
--EDIT--
Here is the XAML for my LiteGrid usercontrol -
<UserControl x:Class="ReportUtility.Controls.LiteGrid.LiteGrid"
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:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
xmlns:lite="clr-namespace:ReportUtility.Controls.LiteGrid"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ScrollViewer x:Name="_scroll" VerticalScrollBarVisibility="Hidden" HorizontalScrollBarVisibility="Hidden">
<ItemsControl ItemsSource="{Binding Columns}" Grid.Row="0" Background="AliceBlue">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</ScrollViewer>
<WindowsFormsHost Background="White" Grid.Row="1">
<lite:LiteGridView x:Name="_liteGridView"/>
</WindowsFormsHost>
</Grid>
My main view model is:
public class MainWindowViewModel : DependencyObject
{
private readonly ILiteTableSource _source;
public ICommand ExecuteQueryCommand { get; set; }
public LiteGridViewModel Grid { get; set; }
public string SqlCommandText { get; set; }
public MainWindowViewModel(ILiteTableSource source)
{
this.ExecuteQueryCommand = new ExecuteQueryCommand(this);
_source = source;
_source.DataArrived+=new Action<DataSources.LiteSource.LiteTable>(_source_DataArrived);
}
public void ExecuteQuery()
{
_source.Connection = new ServerConnection();
_source.CommandText = this.SqlCommandText;
_source.ExecuteQuery();
}
public LiteTable Results
{
get { return (LiteTable)GetValue(ResultsProperty); }
set { SetValue(ResultsProperty, value); }
}
// Using a DependencyProperty as the backing store for Results. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ResultsProperty =
DependencyProperty.Register("Results", typeof(LiteTable), typeof(MainWindowViewModel), new UIPropertyMetadata(null));
void _source_DataArrived(LiteTable data)
{
this.Results = data;
}
}
And the XAML:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="50"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Button Grid.Row="0" Content="TestButton" HorizontalAlignment="Stretch" Command="{Binding ExecuteQueryCommand}"/>
<TextBox Grid.Row="1" Text="{Binding Path=SqlCommandText, UpdateSourceTrigger=PropertyChanged}"/>
<lite:LiteGrid Grid.Row="2" Data="{Binding Data, UpdateSourceTrigger=PropertyChanged}"/>
</Grid>
Since you have a LiteGridViewModel to go with your LiteGrid, why not just execute the command from the ViewModel?
Using the code posted in your question, I would:
Add this to the Resources to make sure that LiteGridViewModel is drawn using LiteView
<Window.Resources> <!-- Or Grid.Resources if you prefer -->
<DataTemplate DataType="{x:Type lite:LiteGridViewModel}">
<lite:LiteGrid />
</DataTemplate>
</Window.Resources>
Replace the <lite:LiteGrid ... /> control in the MainView with a ContentControl to display the ViewModel
<ContentControl Content="{Binding Grid}" />
Remove the Data Property on the MainViewModel since it should be stored in LiteGridViewModel, not MainViewModel
And in your MainWindowViewModel work with the LiteGridViewModel instead of trying to work with the ViewModel via the View
Grid = new LiteGridViewModel();
void _source_DataArrived(LiteTable data)
{
Grid.Data = data; // Fill property in ViewModel
Grid.UpdateData(); // Call command on ViewModel
}
public LiteTable Data
{
get { return (LiteTable)GetValue(DataProperty); }
set
{
object oldvalue = Data;
SetValue(DataProperty, value);
OnPropertyChanged(new DependencyPropertyChangedEventArgs(DataProperty, oldvalue, value));
}
}
// Using a DependencyProperty as the backing store for Data. This enables animation, styling, binding, etc...
public static readonly DependencyProperty DataProperty =
DependencyProperty.Register("Data", typeof(LiteTable), typeof(LiteGrid), new UIPropertyMetadata(null));
try this...

Categories

Resources