如何使用VisualState AdaptiveTrigger更改ListView Item FontSize

时间:2017-06-26 00:34:10

标签: c# xaml uwp windows-10-universal

我使用Visual State Adaptive Trigger根据有效的屏幕分辨率更改页面外观。这很好用,但我不能让它适用于ListView项目。

我的ListView看起来像这样:

<ListView x:Name="listView" >
    <ListView.ItemTemplate>
        <DataTemplate>
                <TextBlock FontSize="20" Text="{Binding MyItem}"/>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

我可以在XAML中静态更改TextBlock字体大小。但我不知道如何在VisualState setter target中引用它。由于自动生成了子,我无法给TextBlock一个名字。我的视觉状态代码如下。我放了???我想在哪里引用ListView TextBlock项目FontSize。

 <VisualStateManager.VisualStateGroups>
    <VisualStateGroup>
            <VisualState x:Name="NormalStateReadView">
                    <!-- VisualState to be triggered when window width is <720 effective pixels -->
                    <VisualState.StateTriggers>
                        <AdaptiveTrigger MinWindowWidth="0" />
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter Target="???" Value="20" />
                    </VisualState.Setters>
                </VisualState>
    </VisualStateGroup>

    <VisualStateGroup>
            <VisualState x:Name="NormalStateReadView">
                    <!-- VisualState to be triggered when window width is >=720 effective pixels -->
                    <VisualState.StateTriggers>
                        <AdaptiveTrigger MinWindowWidth="720" />
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter Target="???" Value="30" />
                    </VisualState.Setters>
                </VisualState>
    </VisualStateGroup>

任何帮助表示感谢。

2 个答案:

答案 0 :(得分:3)

您需要将模板包装在UserControl内,以使自适应触发器正常工作;视觉状态也应该进入模板内部,并确保它位于Grid的第一个直接孩子(即UserControl)之下。我看到你定义了两个视觉状态组,但实际上你只需要一个。

<ListView.ItemTemplate>
    <DataTemplate>
        <UserControl>
            <Grid>
                <VisualStateManager.VisualStateGroups>
                    <VisualStateGroup>
                        <VisualState x:Name="NarrowState">
                            <VisualState.StateTriggers>
                                <AdaptiveTrigger MinWindowWidth="0" />
                            </VisualState.StateTriggers>

                            <VisualState.Setters>
                                <Setter Target="Title.(TextBlock.FontSize)" Value="24" />
                            </VisualState.Setters>
                        </VisualState>

                        <VisualState x:Name="WideState">
                            <VisualState.StateTriggers>
                                <AdaptiveTrigger MinWindowWidth="720" />
                            </VisualState.StateTriggers>

                            <VisualState.Setters>
                                <Setter Target="Title.(TextBlock.FontSize)" Value="36" />
                            </VisualState.Setters>
                        </VisualState>
                    </VisualStateGroup>
                </VisualStateManager.VisualStateGroups>

                <TextBlock x:Name="Title" Text="{Binding Property1}" />
            </Grid>
        </UserControl>
    </DataTemplate>
</ListView.ItemTemplate>

更新

以下是我认为更灵活的解决方案。它需要一些代码来设置,但结果是你得到干净,可重用和可读的代码。

我们的想法是获取顶级VisualStateGroup的引用,该引用位于ListView 之外,大部分位于Page级。

然后,创建三个VisualState s(即 Narrow Normal &amp; Wide )并将它们附加到一个新{ {1}}应该属于VisualStateGroup的第一个孩子。

一旦我们引用了这两个UserControl,我们就可以监控顶级的VisualStateGroup并相应地更新第二个中的状态。

上述所有逻辑都可以由UWP XAML Behavior nuget package中的CurrentStateChanged包裹。

Behavior到位后,您可以将内部状态定义为 -

Behavior

工作演示

enter image description here

随时查看工作样本here

答案 1 :(得分:1)

我们无法将from Tkinter import * class GUI: def __init__(self): """initialization""" # widgets self.window = Tk() get_string = Button( self.window, command = self.on_get_string, text = "Open string" ) # pack the widgets get_string.pack() return def main(self): """the main method""" self.window.mainloop() return def on_get_string(self, event = None): """open the string window""" prompt = PromptString() # a dialog which prompts for a string print str(prompt.string) # None prompt.wait(self.window) # wait for the prompt print str(prompt.string) return class PromptString: def __init__(self): """initialization""" self.string = None # the string # widgets self.window = Toplevel() self.input = Entry(self.window) self.input.bind("<Return>", self.on_set_string) set_button = Button( self.window, command = self.on_set_string, text = "Set" ) # pack the widgets self.input.pack(side = LEFT) set_button.pack(side = RIGHT) return def main(self): """the main method""" self.window.mainloop() # execution pauses after this line finishes return def get_input(self): """get the input""" return self.input.get() def on_set_string(self, event = None): """set the string variable and close the window""" self.string = self.get_input() self.window.destroy() return def wait(self, other_window): """run the window as an offshoot of another window""" other_window.wait_window(self.window) return GUI().main() 用于AdaptiveTrigger内的元素。您应该使用UserControl来执行此操作。这answer可能会对您有所帮助。如果您想要video tutorial,那么此视频可能会对您有所帮助。但我有一点解决方法。

以下是我的方法:

  1. DataTemplate之外创建TextBlock并设置DataTemplate

    Visibility="Collapsed"

    注意:您也可以使用BindableValueHolder代替此,并使用<TextBlock Name="SetFontSize" Visibility="Collapsed"/> 设置它的Value属性。

    AdaptiveTrigger
  2. 使用<helpers:BindableValueHolder x:Name="SetFontSize"/> 更改此AdaptiveTrigger的{​​{1}}

    FontSize
  3. 数据绑定TextBlock <VisualStateManager.VisualStateGroups> <VisualStateGroup> <VisualState x:Name="NormalStateReadView"> <VisualState.StateTriggers> <AdaptiveTrigger MinWindowWidth="0" /> </VisualState.StateTriggers> <VisualState.Setters> <Setter Target="SetFontSize.FontSize" Value="20" /> </VisualState.Setters> </VisualState> </VisualStateGroup> <VisualStateGroup> <VisualState x:Name="WideStateReadView"> <VisualState.StateTriggers> <AdaptiveTrigger MinWindowWidth="720" /> </VisualState.StateTriggers> <VisualState.Setters> <Setter Target="SetFontSize.FontSize" Value="30" /> </VisualState.Setters> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups> FontSize到外TextBlock

    DataTemplate
  4. 以下是您的代码:

    TextBlock