【问题标题】:How to dynamically change columns with rows so WPF UserControl appearance is different for each screen如何动态更改带有行的列,以便每个屏幕的 WPF UserControl 外观不同
【发布时间】:2023-03-16 17:42:01
【问题描述】:

我有一个由两个网格组成的 UserControl。

网格中有两列并排,此网格具有水平布局。 第 0 列有一个数据,第 1 列有另一个数据。

我需要这个控件才能根据显示该控件的屏幕将布局从水平更改为垂直,因此第 0 行和第 1 行应该显示数据,而不是让第 0 列和第 1 列显示数据现在显示数据。

最好的方法是什么?

谢谢

【问题讨论】:

    标签: c# wpf


    【解决方案1】:

    尝试使用 StackPanel 并将属性 OrientationHorizontal 更改为 Vertical

    【讨论】:

      【解决方案2】:

      您可以使用ControlTemplatesDataTriggers 来选择此选项,如果您想要比 StackPanel 提供的更多控制权。这是一个简单粗暴的例子。

      请注意,您可以在不使用 UserControl 的情况下执行此操作。我只是停留在您的描述范围内。

      用户控制

      <UserControl>
          <UserControl.Resources>
              <ControlTemplate x:Key="usingColumns">
                  <Grid>
                      <Grid.ColumnDefinitions>
                          <ColumnDefinition Width="*" />
                          <ColumnDefinition Width="*" />
                      </Grid.ColumnDefinitions>
      
                      <ListBox Grid.Column="0" ItemsSource="{Binding DataOneItems}" />
                      <ListBox Grid.Column="1" ItemsSource="{Binding DataTwoItems}" />
                  </Grid>
      
              </ControlTemplate>
              <ControlTemplate x:Key="usingRows">
                  <Grid>
                      <Grid.RowDefinitions>
                          <RowDefinition Height="*" />
                          <RowDefinition Height="*" />
                      </Grid.RowDefinitions>
      
                      <ListBox Grid.Row="0" ItemsSource="{Binding DataOneItems}" />
                      <ListBox Grid.Row="1" ItemsSource="{Binding DataTwoItems}" />
                  </Grid>
              </ControlTemplate>
          </UserControl.Resources>
          <UserControl.Style>
              <Style>
                  <Setter Property="UserControl.Template" Value="{StaticResource usingColumns}" />
                  <Style.Triggers>
                      <DataTrigger Binding="{Binding ShowVertically}" Value="true">
                          <Setter Property="UserControl.Template" Value="{StaticResource usingRows}" />
                      </DataTrigger>
                  </Style.Triggers>
              </Style>
          </UserControl.Style>
      </UserControl>
      

      类绑定到用户控件:

      public class UserControlData
      {
          public ReadOnlyObservableCollection<DataTypeOne> DataOneItems
          {
              get
              {
                  ObservableCollection<DataTypeOne> dataOneItems = new ObservableCollection<DataTypeOne>();
                  for (int i = 1; i <= 3; i++)
                      dataOneItems.Add(new DataTypeOne(i));
      
                  return new ReadOnlyObservableCollection<DataTypeOne>(dataOneItems);
              }
          }
      
          public ReadOnlyObservableCollection<DataTypeTwo> DataTwoItems
          {
              get
              {
                  ObservableCollection<DataTypeTwo> dataTwoItems = new ObservableCollection<DataTypeTwo>();
                  for (int i = 1; i <= 3; i++)
                      dataTwoItems.Add(new DataTypeTwo(i));
      
                  return new ReadOnlyObservableCollection<DataTypeTwo>(dataTwoItems);
              }
          }
      
          public bool ShowVertically
          {
              get;
              set;
          }
      }
      

      虚拟数据类型(DataTypeOne 和 DataTypeTwo 相同,只是类名不同):

      public class DataTypeOne
      {
          private readonly int mId = 0;
      
          public DataTypeOne(int id)
          {
              mId = id;
          }
      
          public int ID
          {
              get { return mId; }
          }
      
          public override string ToString()
          {
              return String.Format("I am a DataTypeOne with ID {0}", mId.ToString("N"));
          }
      }
      

      关键是ControlTemplates(一个是水平的,一个是垂直的)和Style上的DataTrigger。

      【讨论】:

      • 感谢您的回答。我是 WPF 新手,需要一些说明。假设您在 ControlTemplate 中使用的 ListBox 有一个名称 ListBoxName,并且您想从后面的代码中引用它,如下所示:this.ListBoxName。这样做的方法是什么,因为它在 ControlTemplate 内部,所以后面的代码会产生一个编译错误,说我的 xaml 不包含 ListBoxName 的定义...谢谢
      • 这里是one of many SO 上的示例,或者只是谷歌它。
      猜你喜欢
      • 1970-01-01
      • 2013-02-06
      • 2011-03-24
      • 1970-01-01
      • 1970-01-01
      • 2020-06-08
      • 2016-06-09
      • 2020-10-12
      • 2022-01-25
      相关资源
      最近更新 更多