【问题标题】:WinUI 3 (0.8.1), C++/WinRT (2.0.210714.1), Desktop - Using "BindingOperations::SetBinding(...)WinUI 3 (0.8.1)、C++/WinRT (2.0.210714.1)、桌面 - 使用“BindingOperations::SetBinding(...)
【发布时间】:2021-09-28 02:06:16
【问题描述】:

我将 Xaml 中的 ListBox 绑定到 NetworkViewModel 实例,该实例包含 NodeViewModel 实例的集合。 NodeViewModel 实例应显示在画布上的 X 和 Y 位置,由 NodeViewModel 提供。

我想绑定ListBoxItem的Canvas。左和帆布。从顶部到 X 和 Y。我假设在 WinUI 中不可能在样式中使用绑定。一种解决方法可能是一个辅助类,它带有绑定源路径的附加属性。它在 helper 属性的 PropertyChangedCallback 后面的代码中创建绑定。但是绑定不起作用,为什么?

void BindingHelperNodes::OnBindingPathPropertyChanged( winrt::Microsoft::UI::Xaml::DependencyObject const& d,
winrt::Microsoft::UI::Xaml::DependencyPropertyChangedEventArgs const& e )
{
   if(Microsoft::UI::Xaml::Controls::ListBoxItem item{ d.try_as<Microsoft::UI::Xaml::Controls::ListBoxItem>() })
     {
         Microsoft::UI::Xaml::Controls::Canvas::LeftProperty;
        
         Microsoft::UI::Xaml::Data::Binding binding;
         binding.Mode( Microsoft::UI::Xaml::Data::BindingMode::OneWay );
         Microsoft::UI::Xaml::PropertyPath propertyPath( L"Y" );
         binding.Path( propertyPath );
         Microsoft::UI::Xaml::Data::RelativeSource relativeSource;
         relativeSource.Mode( Microsoft::UI::Xaml::Data::RelativeSourceMode::Self );
         binding.RelativeSource( relativeSource );
                
         Microsoft::UI::Xaml::Data::BindingOperations::SetBinding(
             d,
             Microsoft::UI::Xaml::Controls::Canvas::LeftProperty(),
             binding);
         //item.SetBinding( Microsoft::UI::Xaml::Controls::Canvas::LeftProperty(), binding );
     }
 }



 <Grid>
     <Grid.Resources>
         <ResourceDictionary>
             <Style x:Name="listBoxItemContainerStyle2" TargetType="ListBoxItem">
                 <Setter Property="Canvas.Left" Value="0"/>
             </Style>
         </ResourceDictionary>
     </Grid.Resources>
     <ListBox Grid.Row="1" ItemsSource="{x:Bind mainViewModel.NetworkViewModel.Nodes, Mode=OneWay}"
         >
         <ItemsControl.ItemContainerStyle>
             <Style TargetType="ListBoxItem">
                 <Setter Property="local:BindingHelperNodes.CanvasLeftBindingPath" Value="X"/>
             </Style>
         </ItemsControl.ItemContainerStyle>
         <ListBox.Template>
             <ControlTemplate TargetType="ListBox">
                 <ItemsPresenter />
             </ControlTemplate>
         </ListBox.Template>
         <ListBox.ItemsPanel>
             <ItemsPanelTemplate>
                 <Canvas Background="Transparent" />
             </ItemsPanelTemplate>
         </ListBox.ItemsPanel>
         <ListBox.ItemTemplate>
             <DataTemplate x:DataType="local:NodeViewModel">
                 <Grid
                     Width="120"
                     Height="60"
                     >
                     <!-- This rectangle is the main visual for the node. -->
                     <Rectangle
                         Stroke="Black"
                         Fill="White"
                         RadiusX="40"
                         RadiusY="40" 
                     />
             </DataTemplate>
         </ListBox.ItemTemplate>
     </ListBox>
 </Grid>

【问题讨论】:

    标签: data-binding c++-winrt winui


    【解决方案1】:

    我很幸运找到了问题!真正的问题是第 13 行中对 SetBinding() 的调用,它没有任何效果。但是我居然忘了在IDL文件中设置属性“[Microsoft.UI.Xaml.Data.Bindable]”!

    IDL 文件:

     namespace NetworkView
     {   
         [Microsoft.UI.Xaml.Data.Bindable]
         runtimeclass NodeViewModel : Microsoft.UI.Xaml.Data.INotifyPropertyChanged
         {
             // Declaring a constructor (or constructors) in the IDL causes the runtime class to be
             // activatable from outside the compilation unit.
             NodeViewModel();
        
             String Name;
             Double X;
             Double Y;
         }
     }
    

    创建绑定的 CPP 文件:

    void BindingHelperNodes::OnBindingPathPropertyChanged( winrt::Microsoft::UI::Xaml::DependencyObject const& d, winrt::Microsoft::UI::Xaml::DependencyPropertyChangedEventArgs const& e )
     {
         if(Microsoft::UI::Xaml::Controls::ListBoxItem item{ d.try_as<Microsoft::UI::Xaml::Controls::ListBoxItem>() })
         {
             Microsoft::UI::Xaml::Data::Binding binding;
             binding.Mode( Microsoft::UI::Xaml::Data::BindingMode::OneWay );
             Microsoft::UI::Xaml::PropertyPath propertyPath( L"X" );
             binding.Path( propertyPath );
                    
             // Alternative 1 works
             //Microsoft::UI::Xaml::Data::BindingOperations::SetBinding(
             //    d,
             //    Microsoft::UI::Xaml::Controls::Canvas::LeftProperty(),
             //    binding);
             // Alternative 2 works, too
             item.SetBinding( Microsoft::UI::Xaml::Controls::Canvas::LeftProperty(), binding );
         }
     }
    

    最好的问候 阿尔弗雷德

    【讨论】:

    • 你可以accept your own answer,这样,越来越多的会员面临同样的问题,可以知道这个问题并迅速得到帮助。
    猜你喜欢
    • 2022-08-24
    • 2022-10-14
    • 2021-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-13
    • 2022-10-04
    • 2022-10-04
    相关资源
    最近更新 更多