Reputation: 1290
I have an issue with my binding in WPF currently. I have a two-tabbed application. The first tab contains a datagrid control that is populated by a list. The second tab contains a listbox control that is populated by a list. The problem is if I run the check on the first tab and it returns for example 5 rows in the datagrid, the second tab will populate 5 dummy listbox items. So the controls are evidently sharing the some context, but I'm unsure how to correct that.
XAML for first tab showing binding:
<DataGrid Name="WinUpdateDataGrid" Margin="10,79,0,114" ItemsSource="{Binding}" CanUserAddRows="false" AutoGenerateColumns="true" HorizontalAlignment="Left" VerticalAlignment="Center" ColumnWidth="*" Height="161" Width="509" MaxHeight="150" MaxWidth="700"></DataGrid>
Code for first tab showing datacontext:
private void CheckforWindowsUpdates_Click(object sender, RoutedEventArgs e)
{
CheckforWindowsUpdates.IsEnabled = false;
WinUpdateStatusText.Text = "Evaluation in progress...";
WinUpdateProgressBar.Visibility = Visibility.Visible;
WinUpdateProgressBar.IsIndeterminate = true;
worker = new BackgroundWorker();
worker.WorkerReportsProgress = true;
worker.WorkerSupportsCancellation = true;
DataContext = WindowsUpdate.updateClassList;
worker.DoWork += delegate(object s, DoWorkEventArgs args)
{
WindowsUpdate.getCollectionofMissingSecurityUpdates(WindowsUpdate.windowsKBExceptionsList, WindowsUpdate.CabFilePath);
};
worker.ProgressChanged += delegate(object s, ProgressChangedEventArgs args)
{
};
worker.RunWorkerCompleted += delegate(object s, RunWorkerCompletedEventArgs args)
{
CheckforWindowsUpdates.IsEnabled = true;
WinUpdateStatusText.Text = "Evaluation completed. Missing the following updates:";
WinUpdateProgressBar.IsIndeterminate = false;
WinUpdateProgressBar.Visibility = Visibility.Hidden;
if (WindowsUpdate.updateClassList.Count > 0)
{
WinUpdateDataGrid.Visibility = Visibility.Visible;
DownloadandInstallWinUpdatesButton.Visibility = Visibility.Visible;
}
else
{
WinUpdateDataGrid.Visibility = Visibility.Hidden;
WinUpdateStatusText.Text = "Evaluation completed. No missing updates.";
}
};
worker.RunWorkerAsync();
}
XAML for second tab:
<ListBox Name="ThirdPartyListBox" ItemsSource="{Binding}" Margin="0,70,0,0">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="C:\Users\Test\Desktop\Project\ACME-WPF\ACME-WPF\window-new-3.ico" Margin="5" Width="50"/>
<Button Name="ThirdPartyInstallButton" Content="Install" Click="InstallThirdPartyUpdatesButton_Click" Margin="5,5,0,0" Height="25"></Button>
<Button Name="ThirdPartyPostoneButton" Content="Postpone" Margin="5,5,0,0" Height="25"></Button>
<TextBlock FontWeight="Bold" Text="{Binding Item2.Name}" Margin="12,25,0,0"/>
<TextBlock FontWeight="Bold" Text="{Binding Item2.RequiredVersion}" Margin="3,25,0,0"/>
<TextBlock Text="{Binding Item2.CustomUIMessage}" Margin="10,25,0,0" TextWrapping="Wrap" Foreground="Red"/>
<TextBlock Text="You have used " Margin="3,25,0,0"/>
<TextBlock Text="{Binding Item3.UsedDeferrals}" Margin="3,25,0,0"/>
<TextBlock Text=" of " Margin="3,25,0,0"/>
<TextBlock Text="{Binding Item2.MaxDefferals}" Margin="3,25,0,0"/>
<TextBlock Text=" deferrals for this update." Margin="3,25,0,0"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Code for second tab:
private void CheckforThirdPartyUpdatesButton_Click(object sender, RoutedEventArgs e)
{
CheckforThirdPartyUpdatesButton.IsEnabled = false;
worker = new BackgroundWorker();
worker.WorkerReportsProgress = true;
worker.WorkerSupportsCancellation = true;
DataContext = RegScan_ThirdParty.comparisonListWithState;
worker.DoWork += delegate(object s, DoWorkEventArgs args)
{
MainEntry.checkFor3PUpdates();
};
worker.ProgressChanged += delegate(object s, ProgressChangedEventArgs args)
{
};
worker.RunWorkerCompleted += delegate(object s, RunWorkerCompletedEventArgs args)
{
CheckforThirdPartyUpdatesButton.IsEnabled = true;
};
worker.RunWorkerAsync();
}
Full XAML by request:
<Window x:Class="ACME_WPF.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ACME" Height="411.085" MaxWidth="555.668"
SizeToContent="WidthAndHeight" WindowStartupLocation="CenterScreen"
WindowStyle="ToolWindow"
>
<Grid>
<TabControl>
<TabItem Header="Windows Updates">
<Grid>
<Image Name="WindowsUpdateDefaultImage" Source="C:\Users\Test\Desktop\Project\ACME-WPF\ACME-WPF\windowsupdate.png" Margin="0,16,488,286" Width="50"/>
<TextBlock Name="WinUpdateStatusText" Width="Auto" HorizontalAlignment="Left" Margin="267,22,0,0" TextWrapping="Wrap" Text="{Binding Path=WindowsUpdateCompliance, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" FontSize="14" Foreground="DarkSlateBlue"/>
<Button Name="CheckforWindowsUpdates" HorizontalAlignment="Left" Margin="54,18,0,0" VerticalAlignment="Top" Width="207" Content="Check for Windows Security Updates" Height="25" Click="CheckforWindowsUpdates_Click"/>
<ProgressBar Name="WinUpdateProgressBar" HorizontalAlignment="Left" Height="18" Margin="54,52,0,0" VerticalAlignment="Top" Width="207"/>
<DataGrid Name="WinUpdateDataGrid" Margin="10,79,0,114" ItemsSource="{Binding}" CanUserAddRows="false" AutoGenerateColumns="true" HorizontalAlignment="Left" VerticalAlignment="Center" ColumnWidth="*" Height="161" Width="509" MaxHeight="150" MaxWidth="700"></DataGrid>
<Button Name="DownloadandInstallWinUpdatesButton" Content="Download and Install Windows Updates" HorizontalAlignment="Left" Margin="10,250,0,0" VerticalAlignment="Top" Width="227" Height="26" Click="DownloadandInstallWinUpdatesButton_Click"/>
<ProgressBar Name="DownloadandInstallWinUpdatesButtonProgressBar" HorizontalAlignment="Left" Height="26" Margin="10,286,0,0" VerticalAlignment="Top" Width="227"/>
<TextBlock Name="WinUpdateInstallationText" HorizontalAlignment="Left" Margin="256,250,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="Auto"/>
</Grid>
</TabItem>
<TabItem Header="Third Party Updates">
<Grid>
<Button Name="CheckforThirdPartyUpdatesButton" Content="Check for Third Party Updates" Margin="10,11,339,304" Click="CheckforThirdPartyUpdatesButton_Click" MaxWidth="200"/>
<ListBox Name="ThirdPartyListBox" ItemsSource="{Binding}" Margin="0,70,0,0">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="C:\Users\Test\Desktop\Project\ACME-WPF\ACME-WPF\window-new-3.ico" Margin="5" Width="50"/>
<Button Name="ThirdPartyInstallButton" Content="Install" Click="InstallThirdPartyUpdatesButton_Click" CommandParameter="{Binding Path=.}" Command="{Binding ElementName=ThirdPartyListBox, Path=DataContext.InstallComponentCommand}" Margin="5,5,0,0" Height="25"></Button>
<Button Name="ThirdPartyPostoneButton" Content="Postpone" Margin="5,5,0,0" Height="25"></Button>
<TextBlock FontWeight="Bold" Text="{Binding Item2.Name}" Margin="12,25,0,0"/>
<TextBlock FontWeight="Bold" Text="{Binding Item2.RequiredVersion}" Margin="3,25,0,0"/>
<TextBlock Text="{Binding Item2.CustomUIMessage}" Margin="10,25,0,0" TextWrapping="Wrap" Foreground="Red"/>
<TextBlock Text="You have used " Margin="3,25,0,0"/>
<TextBlock Text="{Binding Item3.UsedDeferrals}" Margin="3,25,0,0"/>
<TextBlock Text=" of " Margin="3,25,0,0"/>
<TextBlock Text="{Binding Item2.MaxDefferals}" Margin="3,25,0,0"/>
<TextBlock Text=" deferrals for this update." Margin="3,25,0,0"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</TabItem>
<TabItem Header="Information">
<Grid>
<Label Name="Info_ComputerNameLabel" Content="Computer Name: " Margin="10,13,397,253" RenderTransformOrigin="0.49,1"/>
<Label Name="Info_UserNameLabel" Content="User Name: " Width="100" Margin="10,54,419,222"/>
<Label Name="Info_IPAddressLabel" Content="IP Address: " Width="100" Margin="10,96,419,180"/>
<TextBlock Name="Info_ComputerNameText" HorizontalAlignment="Left" Margin="137,18,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top"/>
<TextBlock Name="Info_UserNameText" HorizontalAlignment="Left" Margin="137,59,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top"/>
<TextBlock Name="Info_IPAddressText" HorizontalAlignment="Left" Margin="137,101,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top"/>
</Grid>
</TabItem>
</TabControl>
</Grid>
Upvotes: 0
Views: 1665
Reputation: 130
My guess would be that you need to set the DataContext specifically to the Grid and the ListBox. Something like this:
WinUpdateDataGrid.DataContext = WindowsUpdate.updateClassList;
and
ThirdPartyListBox.DataContext = RegScan_ThirdParty.comparisonListWithState;
The thing is that if the two functions CheckforWindowsUpdates_Click
and CheckforThirdPartyUpdatesButton_Click
is precent in the same codebehind file they will set the same DataContext and the binding ItemsSource="{Binding}"
in the Grid and the ListBox will inherit the same DataContext.
Upvotes: 1
Reputation: 10865
Short answer:{Binding}
is not a shortcut for "binding to itself" (in the sense of RelativeSource.Self). Rather, {Binding}
is equivalent to {Binding Path=.}
, which binds to the current source.
To elaborate: A binding has a source and a path. You can do a "binding to itself", for example, by using
<myUIControl myProperty="{Binding RelativeSource={RelativeSource Self}, Path=x}" />
This, however, sets the source to the control itself, so it will try to access property x
of the UI control (rather than property x
of the current data context). From how I understood your question, this is not what you want; in particular, it is not what {Binding}
does: {Binding}
keeps the source as it is (usually the DataContext
of some parent element) and binds to the source itself (equivalent to Path=.
).
It's possible that your current source for two controls are being shared. I would just explicitly set the Binding
datasource rather than doing the shortcut method
Update:
It is really sharing the DataContext. Can you just create two public properties for those DataContext
and do the Binding
from there. Don't forget to implement INotifyPropertyChanged
and call the implementation when the properties are being set. That way it is more clear and readable to other developers that there are really two datacontext
for two different controls.
Upvotes: 0