|
You shouldn't need to have access to a child controls VM directly. It's all done via data binding.
<Window>
<Grid>
<MyChildView SomeProp="{Binding SomeProp}" />
</Grid>
</Window>
If you are using DataTemplates to map views <-> VMs, you also don't need access to the VM directly because those views should operate on thier own VMs which would talk to the persistance layer directly.
If you are finding that you need to access a child control/view to do stuff from the code behind, its probably because you didn't expose that functionality with a bindable property. If you don't own the code of the child view, you can expose the functionality you need with a bindable attached behavior.
|
|
|
|
|
Ok, I'm not sure I understand.
In this case I have a Materials view, and on it is a control that lists prices. The prices control is used in more than one view which is why it's a control.
There is a one to many between Materials and Prices, so the prices view needs to know the PK of the Material. In addition, the Material needs to know the count of Prices and other info.
When a material is selected I need to tell the prices view the PK of the selected material so it can load them. When a price is added to the list in the Prices control, the Material view needs to know it.
The Prices control already handles it's own CRUD operations, but I don't understand how it and the Materials view are supposed to intertact. There has to be some way to say "Hey Prices view, give me your data" or, "Hey Prices view, load the prices for this Material".
Using Data Templates to map them seems to make it impossible since the VM for the Materials has no clue that there's a Prices control any where.
If it's not broken, fix it until it is
|
|
|
|
|
Yeah, so its like what I said. Assuming I get what you are talking about . Psuedo-code:
<Window>
<MaterialView />
</Window>
<MaterialView>
<ListView Name="lv" ItemsSource="{Binding ListOfMaterials}" />
<PriceControl Source="{Binding ElementName=lv, Path=SelectedItem.PK}" />
</MaterialView>
Then your PriceControl would auto-magically know when a different material has been selected. But it needs to expose a property that can be data-bound.
EDIT: I just noticed in your response that you wanted to go both ways, so you can do something like:
<MaterialView>
<Label Content="{Binding ElementName=pc, Path=Count" />
</MaterialView>
You just need to expose everything you want to transfer back and forth as a property in the VMs.
The key here is to use the ElementName binding.
|
|
|
|
|
I see. Thanks!
If it's not broken, fix it until it is
|
|
|
|
|
OK, I'd like to ask a follow up question...
Using your code as an example, in the case of the PriceControl, I would have to create a Dependency Property on the control called 'Source', correct?
If so, then that code goes in the control's code behind. How do I 'connect' that Source property to the PricingControl's view model? What I mean is - the view model doesn't know about the Source property, does it?
If it's not broken, fix it until it is
|
|
|
|
|
PriceControl.cs would have something like:
public class PriceControl : Control
{
public static readonly DependencyProperty SourceProperty = DependencyProperty.Register("Source",
typeof(Whatever), typeof(PriceControl), ...);
}
then in your xaml:
<some random tag>
<some other random tag>
<ListView Name="lv" ItemsSource="{Binding Items}" ... />
<PriceControl Name="priceControl" Source={Binding ElementName="lv", Path="SelectedItem"} ... />
</some other random tag>
</some random tag>
Or something of that nature.
You shouldn't really need to refer to Source in the controls VM... you should do it in the XAML... if you use a DataTemplate to define the control's look, you'll be able to refer to the Source property in there.. {Binding Path=Source}...
if you REALLY need to access it in your VM, I think you mentioned SQL calls or something like that, you could define a property in your VM and bind it to Source in the style.
|
|
|
|
|
It's been a month since we last discussed this. I had to put it aside...
So, this morning I create a Sample User Control[^] app to try to do what you suggested here. For the most part I think it's close.
When a Customer is selected, the control should go get the addresses for it. However, the DP's Getter never fires.
This brings me to a question...
Now that I have the DP in the AddressView code behind, when the CustomerId DP is set, how does the VM know about it? What is the connection between the DP in the Code Behind and the VM?
At any rate, I provided a link to the sample. It's pretty small, and I think I coded what you showed me. I would appreciate you taking a quick look to see if you can spot where I'm wrong.
And thanks for all your help so far.
If it's not broken, fix it until it is
|
|
|
|
|
Hello Listeners,
Working on a silverlight application. The data that needs to be returned is very small (1-4 rows)
My domainservice includes following code to populate a datagrid
public IQueryable<products> GetProductsFiltered(int vendorId)
{
return this.ObjectContext.Products.Where(P => P.VendId == vendorId);
}
When the correct value is provided via a “GetProductsFilteredQuery(2)”, the server returns the data and datagird is properly populated.
Now I need to return data based on a column named SiteID so I added another method
public IQueryable<products> GetProductsFilteredSite(int siteId)
{
return this.ObjectContext.Products.Where(P => P.SiteID == siteId);
}
And call it by something like this “GetProductsFilterSiteQuery(5)” . Compiles fine but but error is generated when running the application:
“Local operation failed for query “ GetProductsFilterSite”. The remote server returned an error: NotFound”.
Run the query manually –OK
Fiddler also logs an 504 error “ReadResponse() failed: The server did not return a response for this request.”
But also shows a valid argument passed to GetProductsFilterSiteQuery() method
Any idea is greatly appreciated
|
|
|
|
|
You can try out two things -
1) If you are deploying your service on IIS, you will need to redeploy after adding the new method.
2) You will need to update your service proxy. If you added the website manually, then just right click on the service and refresh.
|
|
|
|
|
Re-publishing the domain services solved my problem.
Many thanks for the help Abhinav
|
|
|
|
|
How to achieve the below layout ? I am new to Silverlight. I need to achieve the same with Paging. Which one is better DataGrid or ListBox ? Can i achieve the same with normal Silverlight but with paging? I dn't want a column header and also my row should have the details filled with Image,Links,Text etc as below...
I want to achieve the same Layout as given in the link http://demos.devexpress.com/AgDataGridDemos/ under the Customization/Row Template tab with Filtering,Sorting and paging functionalities using normal Silverlight Controls. I have to hide the Headers also.
Note: In the example,u can see only Rowtemplate.I wanna acheive exactly same Layout.Go to Link and Click Customization/Row Template tab
|
|
|
|
|
Since you use a number of features like filtering and sorting, you could go for a grid rather than a listbox.
If you want to go for light code and avoid a heavy grid loading on your page, you could still consider using the listbox and build sorting and filtering features into it.
|
|
|
|
|
I have a SL application that I have been working. Make little changes and save a back up so I can roll it back if a problem so I have a few backups.
Today I open the project and the page generated an error. Although I can compiled successfully, the error is when I view page in designer. " ArgumentException was thown on parameter": The myMethod method does not have an argument that matches the querParameter collection".
Then I tried to load a previous project and shows the same thing, as of matter of fact, all of them have the same problem now. What a…!!!
Problem points to
<riaControls:Parameter ParameterName="argType" Value="{Binding ElementName=argTypeTextBox, Path=Text}" />
The code is below. Any help is greatly appreciated
<navigation:Page x:Class="EclipseMTX.Views.Protons"
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"
mc:Ignorable="d"
xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
d:DesignWidth="1200" d:DesignHeight="724"
Title="Protons Page" BorderBrush="#FF834F4F" xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" xmlns:riaControls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.DomainServices" xmlns:my="clr-namespace:EclipseMTX.Web">
<Grid x:Name="LayoutRoot" Background="#FF0E0E0E" Width="1196" Height="728">
<sdk:DataGrid AutoGenerateColumns="True" AutoGeneratingColumn="DGPro_AutoGeneratingColumn" Height="263" HorizontalAlignment="Left" Margin="135,86,0,0" Name="dataGrid1" VerticalAlignment="Top" Width="1049" Background="#F3333333" Foreground="WhiteSmoke" RowBackground="#F3333335" VerticalScrollBarVisibility="Disabled" />
<sdk:Label Height="45" HorizontalAlignment="Left" Margin="439,28,0,0" Name="label1" VerticalAlignment="Top" Width="324" Content="Proton Installed base" Foreground="WhiteSmoke" FontSize="28" />
<sdk:DataPager Height="26" HorizontalAlignment="Left" Margin="135,347,0,0" Name="dataPager1" PageSize="10" VerticalAlignment="Top" Width="1051" Background="#F3333333" Cursor="Hand" Foreground="WhiteSmoke" />
<Button Content="Run Query" Height="23" HorizontalAlignment="Left" Margin="19,355,0,0" Name="button1" VerticalAlignment="Top" Width="102" Click="button1_Click" />
<riaControls:DomainDataSource AutoLoad="False" d:DesignData="{d:DesignInstance my:Proton, CreateList=true}" Height="0" LoadedData="protonDomainDataSource_LoadedData" Name="protonDomainDataSource" QueryName="GetProtonsFiltered" Width="0">
<riaControls:DomainDataSource.DomainContext>
<my:EclipseMTXDomainContext />
</riaControls:DomainDataSource.DomainContext>
<riaControls:DomainDataSource.QueryParameters>
<riaControls:Parameter ParameterName="argType" Value="{Binding ElementName=argTypeTextBox, Path=Text}" />
</riaControls:DomainDataSource.QueryParameters>
</riaControls:DomainDataSource>
<StackPanel Height="30" HorizontalAlignment="Left" Orientation="Horizontal" VerticalAlignment="Top"></StackPanel>
<sdk:Label Height="28" HorizontalAlignment="Left" Margin="19,58,0,0" Name="label3" VerticalAlignment="Top" Width="120" Content="By Vendor" Foreground="WhiteSmoke" FontSize="18" />
<sdk:DataGrid AutoGenerateColumns="True" AutoGeneratingColumn="DGPCSN_AutoGeneratingColumn" Height="265" HorizontalAlignment="Left" Margin="135,421,0,0" Name="dataGrid2" VerticalAlignment="Top" Width="1049" Background="#F3333333" RowBackground="#F3333335" Foreground="WhiteSmoke" />
<Button Content="Run Query" Height="23" HorizontalAlignment="Right" Margin="0,509,1084,0" Name="button2" VerticalAlignment="Top" Width="93" Click="button2_Click" />
<ComboBox Height="23" HorizontalAlignment="Right" Margin="0,453,1068,0" Name="comboBox2" VerticalAlignment="Top" Width="120" SelectionChanged="comboBox2_SelectionChanged" />
<sdk:DataPager Height="26" HorizontalAlignment="Left" Margin="135,687,0,0" Name="dataPager2" PageSize="10" VerticalAlignment="Top" Width="1047" Background="#F3333333" Foreground="WhiteSmoke" />
<RadioButton Content="By PcSn" Height="33" HorizontalAlignment="Right" Margin="0,389,1075,0" Name="radioButton1" VerticalAlignment="Top" Foreground="WhiteSmoke" FontSize="18" Width="109" />
<RadioButton Content="By T-Box" Height="33" HorizontalAlignment="Left" Margin="8,421,0,0" Name="radioButton2" VerticalAlignment="Top" Foreground="WhiteSmoke" FontSize="18" Width="131" />
<TextBox Background="#FF0E0E0E" Height="34" HorizontalAlignment="Left" Margin="668,387,0,0" Name="textBox1" VerticalAlignment="Top" Foreground="WhiteSmoke" FontSize="12" Width="428" BorderBrush="Black" />
<ListBox HorizontalAlignment="Left" Margin="12,86,0,0" Name="listBox1" Width="120" Background="#F3333333" Foreground="WhiteSmoke" Height="263" VerticalAlignment="Top" />
</Grid>
</navigation:Page>
|
|
|
|
|
Make sure you have all the third party components installed on the machine.
|
|
|
|
|
I am using WPF, C#, Linq to Sql -- I have a stored procedure and I am trying to bind the results to a treeview two levels deep. Below is some of the code I thought might help understand better, I am not sure if I needed to post this much code, but I can remove the uneeded code. I am having trouble figuring out the bindings with the data-templates. Any suggestions or comments would be appreciated.
Here is part of the view model I am using
public sealed class AViewModel : ViewModel
{
public sealed class ItemsToGet
{
public Guid? Id {get; set; }
public int? TNumber { get; set;}
public string Title { get; set; }
public string Description { get; set; }
public string FullName { get; set;}
}
private Guid mText = Guid.Empty;
private ObservableCollection<ItemsToGet> mHistory = new ObservableCollection<ItemsToGet>();
public ObservableCollection<ItemsToGet> History
{
get
{
return mHistory;
}
}
public Guid SearchText
{
get
{
return mText ;
}
set
{
mText = value;
OnPropertyChanged("SearchText");
}
}
var itemlist = from s in context.GetHistory(mText)
select new ItemsToGet()
{
Id = s.Id,
TNumber = s.TNumber,
Title = s.Title,
Description = s.Description,
FullName = s.FullName
};
List<ItemsToGet> Results = itemlist.ToList();
mHistory.Clear();
Results.ForEach(b => mHistory.Add(b));
Here is the View Code Behind
public partial class AView : UserControl
{
public AView()
{
InitializeComponent();
AViewModel vm = this.DataContext as AViewModel;
}
}
Xaml -- I want to top level to display the Title, and the child(second level to be the TNumber)
<TreeView ItemsSource="{Binding History}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding History}">
<TextBlock Foreground="Red" Text="{Binding Title}" />
<HierarchicalDataTemplate.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding History}">
<TextBlock Text="{Binding TNumber}" />
<HierarchicalDataTemplate.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" />
</DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</UserControl>
Here is a snapshot of what the results look like, there are more rows than this, but this is the format.
Trying to display it like below. Thanks for any comments or suggestions.
Design 1
--Tnumber 1
--TNumber 2
Design 2
--TNumber 1
--TNumber 2
--TNumber 3
Design 3
--TNumber 1
ETC
ETC
|
|
|
|
|
|
You need 2 clases a Design class and a Tnumber class, your Design class must have an observable collection of Tnumbers.
Populate the Design class with the unique of the design field. In the tnumber collection add the records for each design type.
Binid your treeview to the design collection, bind the hierarchy template to the tnumber collection.
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
Trying to use VisualTreeHelper.HitTest on a TreeView. I have two arbitrary items. TreeViewItem1 and TreeViewItem2. These items may appear anywhere on the tree and have any sort of relationship (different parents, etc.). I've gotten the top left point of the two items. pt1 and pt2. I want to find the visible TreeViewItems in between. So I did:
VisualTreeHelper.HitTest(ParentTreeView, new HitTestFilterCallback(A), new HitTestResultCallback(B), new GeometryHitTestParameters(new RectangleGeometry(new Rect(0, pt1.Y, ParentTreeView.ActualWidth, (pt2.Y + 1) - pt1.Y))));
HitTestFilterBehavior A(DependencyObject potentialHitTestTarget)
{
if (potentialHitTestTarget is TreeViewItemEx)
{
if (((UIElement)potentialHitTestTarget).IsVisible)
System.Diagnostics.Debug.WriteLine(potentialHitTestTarget);
}
return HitTestFilterBehavior.Continue;
}
HitTestResultBehavior B(HitTestResult result)
{
return HitTestResultBehavior.Continue;
}
This code is working for the most part, except it's also returning parent items that it shouldn't. If my tree looks like:
1
_2
__3
and the two items in question are 2 & 3, the hit-test also returns 1.
A more ugly example is:
Root
_NodeWithChildren1
_NodeWithChildren2
_NodeWithChildren3
__1
__2
__3
the tree looks exactly like that on the screen. The items in question are _NodeWithChildren3 and __1. The hit-test returns Root and _NodeWithChildren1 and _NodeWithChildren2 as well.
Any ideas? I have confirmed that I am getting the correct item1 & item2 that I think I am getting and I have confirmed that the points I am getting are correct as well.
|
|
|
|
|
Cant you cast the object or check the object using TypeOf, and then check were it is in the treèviewcontrol?
|
|
|
|
|
I posted on this a while back, and I'v tried some things but still cannot get this to work.
The Problem
When I have multiple tabs open, and I click the Close X on a NON-ACTIVE tab, the active tab is closed.
The XAML
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="..\Resources.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style TargetType="{x:Type TabItem}">
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate >
<Grid HorizontalAlignment="Stretch" Height="22">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="20" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="2" ></RowDefinition>
<RowDefinition Height="Auto" ></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Grid.Row="1"
Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type TabItem} }, Path=Header}"
VerticalAlignment="Bottom" Margin="4,0,8,0"/>
<Button Grid.Row="1"
Grid.Column="1"
Height="16"
Width="16"
BorderBrush="{x:Null}"
Background="{x:Null}"
Foreground="#FF224A71"
VerticalAlignment="Center"
Padding="3,0"
Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type TabItem}}, Path=DataContext.CloseTabCommand}">
<TextBlock Text="x"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Margin="0,0,0,2"/>
<Button.ToolTip>
<controls:ToolTipEx Style="{StaticResource TooltipStyle}"
HeaderText="Close"
Icon="/FMG.UI.WPF;component/Media/Images/closetab_24.png"
ContentAreaText="Closes this tab"/>
</Button.ToolTip>
<Button.OpacityMask>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="Black" Offset="0"/>
<GradientStop Color="#4BFFFFFF" Offset="1"/>
</LinearGradientBrush>
</Button.OpacityMask>
</Button>
</Grid>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
</UserControl.Resources>
The problem as I see it is that the view model doesn't know which tab fired the command.
Can someone help me figure this out?
Thanks
If it's not broken, fix it until it is
|
|
|
|
|
I too was running into this same problem with this EXACT command. However this article on c# corner and this article on CP helped me to fix it.
Hope it works!
|
|
|
|
|
I am using this in the code behind for a xaml page and it works fine for retrieving the data for a listbox:
_______________________________________________________________
SLConnDomainContext dbContext = new SLConnDomainContext();
private LoadOperation<Employee> loadOp;
ObservableCollection<Employee> data = new ObservableCollection<Employee>();
public Filters()
{
InitializeComponent();
loadOp = this.dbContext.Load(this.dbContext.GetEmployeesQuery());
loadOp.Completed += new EventHandler(loadOp_Completed);
}
void loadOp_Completed(object sender, EventArgs e)
{
foreach (Employee emp in loadOp.Entities)
{
data.Add(emp);
}
dataForm.ItemsSource = data;
}
I would like to move to a MVVM approach and have created a viewmodel to retrieve the data and pass it into a view by creating an instance of my viewmodel and setting the datacontext property of my listbox. The viewmodel works fine when I am just creating some mock data and populating a list. However, due to the asynchronous nature of using a loadoperation with silverlight, the above code doesn't work with the MVVM approach for me. The data is retrieved but it appears that it is after my view has already loaded so it never appears. Below is my code:
Viewmodel:
______________________________________________________________
{
public partial class EmployeeService
{
private SLConnDomainContext Context = new SLConnDomainContext();
private LoadOperation<Employee> loadOp;
public ObservableCollection<Employee> employees = new ObservableCollection<Employee>();
public EmployeeService()
{
loadOp = Context.Load(Context.GetEmployeesQuery(), LoadBehavior.MergeIntoCurrent, employeeCallBack, null);
}
void employeeCallBack(LoadOperation<Employee> op)
{
foreach (Employee emp in loadOp.Entities)
{
employees.Add(emp);
}
_myEmployees = employees;
MessageBox.Show("I have " + employees.Count + " employees");
}
public IEnumerable<Employee> GetEmployees()
{
return employees;
}
public event PropertyChangedEventHandler PropertyChanged;
private ObservableCollection<Employee> _myEmployees;
public ObservableCollection<Employee> myEmployees
{
get { return _myEmployees; }
set
{
myEmployees = value;
OnPropertyChanged("myEmployees");
}
}
private int _EmployeeID;
public int EmployeeID
{
get { return _EmployeeID; }
set
{
_EmployeeID = value;
OnPropertyChanged("EmployeeID");
}
}
private int _VacationHours;
public int VacationHours
{
get { return _VacationHours; }
set
{
_VacationHours = value;
OnPropertyChanged("VacationHours");
}
}
protected void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
This is set in the constructor for the view's code behind:
______________________________________________________________
public LayoutTest()
{
InitializeComponent();
EmployeeService myservice = new EmployeeService();
EmployeeList.DataContext = myservice;
}
I have the databinding set correclty as it works if I use something like this in place of the above GetEmployees():
______________________________________________________________
public IEnumerable<Employee> GetEmployees()
{
List<Employee> employees = new List<Employee>();
EmployeeService test = new EmployeeService();
foreach (Employee emp in test.GetEmployees())
{
employees.Add(emp);
}
Employee employee = new Employee();
employee.EmployeeID = 1111;
employee.VacationHours = 100;
employees.Add(employee);
employee = new Employee();
employee.EmployeeID = 1112;
employee.VacationHours = 62;
employees.Add(employee);
employee = new Employee();
employee.EmployeeID = 1113;
employee.VacationHours = 132;
employees.Add(employee);
return employees;
}
I am sure this is due to the asynchronous call but I don't know how to fix it. Thanks for any help.
|
|
|
|
|
Why do you have _employees and _myEmployees? The main issue is that _myEmployees = employees doesn't trigger a change notification, so you'd have to call OnPropertyChanged("myEmployees") after the assignment. That is the correct method, but then employees should be a local object, not a class member.
|
|
|
|
|
Wow! Thank you....That was it.
|
|
|
|
|
I could not find no example on how to write a wpf control that wraps c++ win32 window. If some one could provide me with a link to a newbie-like tutorial/documentation (sample code would be good too) on how to create c# libraries that wrap c++ code I would be very thankful.
Thanks in advance.
|
|
|
|
|