question

guessmeifucan-8050 avatar image
0 Votes"
guessmeifucan-8050 asked ·

Issue in using Binding with ElementName in Data Template which is passed through DependencyProperty

In my case, i have a control named MultiSelectListView.xaml which holds the dataTemplate

         <DataTemplate x:Key=&#34;ListTemplate&#34; x:DataType=&#34;model:BaseMultiSelectModel&#34;>
             <Grid Margin=&#34;32,0,20,0&#34; BorderThickness=&#34;0,0,0,1&#34; BorderBrush=&#34;{ThemeResource SystemControlBackgroundChromeMediumBrush}&#34; Background=&#34;Transparent&#34;>
                 <Grid Margin=&#34;0,12,0,12&#34;>
                     <Grid.ColumnDefinitions>
                         <ColumnDefinition Width=&#34;Auto&#34;/>
                         <ColumnDefinition Width=&#34;*&#34;/>
                     </Grid.ColumnDefinitions>
                     <CheckBox IsChecked=&#34;{x:Bind IsChecked, Mode=TwoWay}&#34; MinWidth=&#34;0&#34;/>
                     <ContentControl Grid.Column=&#34;1&#34; HorizontalAlignment=&#34;Stretch&#34; Content=&#34;{Binding}&#34; ContentTemplate=&#34;{Binding ListTemplate, ElementName=MultiSelectList, Mode=OneWay}&#34;/>
                 </Grid>
             </Grid>
         </DataTemplate>


I have a Dependency Property in MultiSelectListView.xaml.cs named ListTemplate which holds the rest of the DataTemplate which i displayed through ContentControl inside DataTemplate.

In my UserView.xaml

     <controls:MultiSelectListView IsLoading=&#34;{x:Bind ProjectUserModel.IsLoading, Mode=OneWay}&#34;
                                   IsSelectallChecked=&#34;{x:Bind ProjectUserModel.IsSelectallChecked, Mode=TwoWay}&#34;
                                   ItemsSource=&#34;{x:Bind ProjectUserModel.ItemsList, Mode=OneWay}&#34;>
         <controls:MultiSelectListView.ListTemplate>
             <DataTemplate x:DataType=&#34;model:UserModel&#34;>
                 <Grid>
                     <Grid.ColumnDefinitions>
                         <ColumnDefinition Width=&#34;300&#34;/>
                         <ColumnDefinition Width=&#34;{Binding IsColumn2Visible, ElementName=UserView, Mode=OneWay}&#34;/>
                         <ColumnDefinition Width=&#34;{Binding IsColumn3Visible, ElementName=UserView, Mode=OneWay}&#34;/>
                     </Grid.ColumnDefinitions>
                     <StackPanel Grid.Column=&#34;0&#34; Margin=&#34;10,0,0,0&#34;>
                         <TextBlock Text=&#34;{x:Bind name, Mode=OneWay}&#34; Style=&#34;{StaticResource TextBlockStyle}&#34;/>
                         <TextBlock Foreground=&#34;{StaticResource SystemControlForegroundBaseMediumBrush}&#34; Margin=&#34;0,5,0,0&#34; Text=&#34;{x:Bind email, Mode=OneWay}&#34; Style=&#34;{StaticResource TextBlockStyle}&#34;/>
                     </StackPanel>
                     <TextBox Grid.Column=&#34;1&#34; VerticalAlignment=&#34;Center&#34; Margin=&#34;5,0,25,0&#34; Text=&#34;{x:Bind value2, Mode=TwoWay}&#34; BorderThickness=&#34;1&#34;/>
                     <TextBox Grid.Column=&#34;2&#34; VerticalAlignment=&#34;Center&#34; Margin=&#34;5,0,25,0&#34; Text=&#34;{x:Bind value3, Mode=TwoWay}&#34; BorderThickness=&#34;1&#34;/>
                 </Grid>
             </DataTemplate>
         </controls:MultiSelectListView.ListTemplate>
     </controls:MultiSelectListView>



In UserView.xaml, x:Bind is working fine. but for binding the column visibility the value will not be available in UserModel. Hence used Binding to fetch from the UserView.xaml.cs. As i used DataTemplate, The Template directly applies to the MultiSelectListView's ContentControl and trying to obtain the IsColumn2Visible, IsColumn3Visible which will not be available there.

My Question is how do i bind the Column visiblity with IsColumn2Visible, ISColumn3Visible ? Please don't prefer individual DependencyProperty on MultiSelectListView.xaml for all Visiblity property, hence the binding ListTemplate is dynamic.

windows-uwpwindows-uwp-xaml
· 5
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Do you mean when you bind IsColumn2Visible, IsColumn3Visible properties with the Width can't work well? And the properties are declared from UserView.xaml.cs instead of UserModel? I noticed you used ElementName method, where is your control which named UserView and have you set the DataContext? Can you please provide a simple sample that can be reproduced for us to test? It will be more helpful to find the issue.

0 Votes 0 · ·

I have already added UserView.xaml code snippet in the question. I haven't set DataContext.

0 Votes 0 · ·

Hai @FayWang-MSFT . I have made a sample project for reproducing the issue. May i know how to share it to u ?

0 Votes 0 · ·
FayWang-MSFT avatar image FayWang-MSFT guessmeifucan-8050 ·

Hi, you can upload it to Github or OneDrive where we can download it.

0 Votes 0 · ·

1 Answer

FayWang-MSFT avatar image
0 Votes"
FayWang-MSFT answered ·

Hello,

​Welcome to our Microsoft Q&A platform!

By checking your code, the reason why IsColumn2Visible and IsColumn3Visible can't work is because your binding targets are in a data template or control template, then its XAML namescope is the XAML namescope of the templated parent. So the XAML namescope of your binding targets is actually MultiSelectListView which named MultiSelectList instead of your UserView. When you set ElementName as UserView, it can't find. So you need to set the ElementName as MultiSelectList.

Update:

Since you can find the 'MultiSelectList' ElementName, so you can set its DataContext as UserView and use DataContext.Column2Width to bind with Width. For example:


UserView:

 <local:MultiSelectListView ItemsSource="{x:Bind Users, Mode=OneWay}">
         <local:MultiSelectListView.ListTemplate>
             <DataTemplate x:DataType="model:UserModel">
                 <Grid Margin="32,0,20,0" Background="Transparent">
                     <Grid Margin="0,12,0,12">
                         <Grid.ColumnDefinitions>
                             <ColumnDefinition Width="100"></ColumnDefinition>
                             <ColumnDefinition Width="{Binding DataContext.Column2Width, ElementName=MultiSelectList, Mode=OneWay}"/>
                             <ColumnDefinition Width="{Binding DataContext.Column3Width, ElementName=MultiSelectList, Mode=OneWay}"/>
                         </Grid.ColumnDefinitions>
                         <TextBlock Text="Hello"/>
                         <TextBlock Grid.Column="1" VerticalAlignment="Center" Margin="5,0,25,0" Text="Column2"/>
                         <TextBlock Grid.Column="2" VerticalAlignment="Center" Margin="5,0,25,0" Text="Column3"/>
                     </Grid>
                 </Grid>
             </DataTemplate>
         </local:MultiSelectListView.ListTemplate>
     </local:MultiSelectListView>

UserView.xaml.cs:

 public MainPage()
 {
     this.InitializeComponent();

     Users.Add(new UserModel());
     Users.Add(new UserModel());

     //Set current DataContext as current page
     this.DataContext = this;
 }
· 3 · Share
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

@FayWang-MSFT Thanks for the reply. I already know the solution what you are derived. The problem is I can't define the those properties in MultiSelectListView.xaml.cs as those properties are UserView specific. MultiSelectListView is a common control where UserView, TaskView etc. uses it for multi selection.

0 Votes 0 · ·
FayWang-MSFT avatar image FayWang-MSFT guessmeifucan-8050 ·

Hi, I have found another easier way, in UserView, set its DataContext as this and the DataContext of MultiSelectListView is also equal to this(UserView). Then using DataContext.Column2Width to bind with your Width of Column. I have updated my answer, you can see more details.

0 Votes 0 · ·

@FayWang-MSFT . Its an easier and an awesome solution. Thanks a lot.

0 Votes 0 · ·