Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
dotNET Platform
wpf
提交
48258a02
W
wpf
项目概览
dotNET Platform
/
wpf
大约 1 年 前同步成功
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
W
wpf
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
48258a02
编写于
2月 26, 2020
作者:
R
Rob LaDuca
浏览文件
操作
浏览文件
下载
差异文件
Merging release/3.1 to master
上级
6ef558b7
5759ba9d
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
188 addition
and
88 deletion
+188
-88
src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft.WinFx.props
...tNet.Wpf/src/PresentationBuildTasks/Microsoft.WinFx.props
+1
-1
src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/DefinitionBase.cs
...tationFramework/System/Windows/Controls/DefinitionBase.cs
+77
-35
src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/Grid.cs
...src/PresentationFramework/System/Windows/Controls/Grid.cs
+2
-2
src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/ItemsControl.cs
...entationFramework/System/Windows/Controls/ItemsControl.cs
+42
-2
src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/VirtualizingStackPanel.cs
...amework/System/Windows/Controls/VirtualizingStackPanel.cs
+9
-9
src/Microsoft.DotNet.Wpf/src/System.Windows.Controls.Ribbon/Microsoft/Windows/Controls/Ribbon/RibbonHelper.cs
....Ribbon/Microsoft/Windows/Controls/Ribbon/RibbonHelper.cs
+15
-6
src/Microsoft.DotNet.Wpf/src/System.Windows.Controls.Ribbon/Microsoft/Windows/Controls/Ribbon/RibbonMenuButton.cs
...bon/Microsoft/Windows/Controls/Ribbon/RibbonMenuButton.cs
+42
-33
未找到文件。
src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft.WinFx.props
浏览文件 @
48258a02
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
<PropertyGroup>
<PropertyGroup>
<_PresentationBuildTasksTfm Condition="'$(MSBuildRuntimeType)' == 'Core'">netcoreapp2.1</_PresentationBuildTasksTfm>
<_PresentationBuildTasksTfm Condition="'$(MSBuildRuntimeType)' == 'Core'">netcoreapp2.1</_PresentationBuildTasksTfm>
<_PresentationBuildTasksTfm Condition="'$(MSBuildRuntimeType)' != 'Core'">net472</_PresentationBuildTasksTfm>
<_PresentationBuildTasksTfm Condition="'$(MSBuildRuntimeType)' != 'Core'">net472</_PresentationBuildTasksTfm>
<_PresentationBuildTasksAssembly Condition="'$(_PresentationBuildTasksAssembly)'==''">$([
System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)..\tools\$(_PresentationBuildTasksTfm)\PresentationBuildTasks.dll'
))</_PresentationBuildTasksAssembly>
<_PresentationBuildTasksAssembly Condition="'$(_PresentationBuildTasksAssembly)'==''">$([
MSBuild]::Unescape($([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)..\tools\$(_PresentationBuildTasksTfm)\PresentationBuildTasks.dll'))
))</_PresentationBuildTasksAssembly>
</PropertyGroup>
</PropertyGroup>
<UsingTask TaskName="Microsoft.Build.Tasks.Windows.MarkupCompilePass1" AssemblyFile="$(_PresentationBuildTasksAssembly)" />
<UsingTask TaskName="Microsoft.Build.Tasks.Windows.MarkupCompilePass1" AssemblyFile="$(_PresentationBuildTasksAssembly)" />
...
...
src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/DefinitionBase.cs
浏览文件 @
48258a02
...
@@ -83,7 +83,7 @@ internal void OnEnterParentTree()
...
@@ -83,7 +83,7 @@ internal void OnEnterParentTree()
{
{
if
(
_sharedState
==
null
)
if
(
_sharedState
==
null
)
{
{
// start with getting SharedSizeGroup value.
// start with getting SharedSizeGroup value.
// this property is NOT inhereted which should result in better overall perf.
// this property is NOT inhereted which should result in better overall perf.
string
sharedSizeGroupId
=
SharedSizeGroup
;
string
sharedSizeGroupId
=
SharedSizeGroup
;
if
(
sharedSizeGroupId
!=
null
)
if
(
sharedSizeGroupId
!=
null
)
...
@@ -167,8 +167,8 @@ internal static void OnUserSizePropertyChanged(DependencyObject d, DependencyPro
...
@@ -167,8 +167,8 @@ internal static void OnUserSizePropertyChanged(DependencyObject d, DependencyPro
parentGrid
.
Invalidate
();
parentGrid
.
Invalidate
();
}
}
else
else
{
{
parentGrid
.
InvalidateMeasure
();
parentGrid
.
InvalidateMeasure
();
}
}
}
}
}
}
...
@@ -411,6 +411,14 @@ internal double MinSizeForArrange
...
@@ -411,6 +411,14 @@ internal double MinSizeForArrange
}
}
}
}
/// <summary>
/// Returns min size, never taking into account shared state.
/// </summary>
internal
double
RawMinSize
{
get
{
return
_minSize
;
}
}
/// <summary>
/// <summary>
/// Offset.
/// Offset.
/// </summary>
/// </summary>
...
@@ -426,7 +434,7 @@ internal double FinalOffset
...
@@ -426,7 +434,7 @@ internal double FinalOffset
internal
GridLength
UserSizeValueCache
internal
GridLength
UserSizeValueCache
{
{
get
get
{
{
return
(
GridLength
)
GetValue
(
return
(
GridLength
)
GetValue
(
_isColumnDefinition
?
_isColumnDefinition
?
ColumnDefinition
.
WidthProperty
:
ColumnDefinition
.
WidthProperty
:
...
@@ -442,8 +450,8 @@ internal double UserMinSizeValueCache
...
@@ -442,8 +450,8 @@ internal double UserMinSizeValueCache
get
get
{
{
return
(
double
)
GetValue
(
return
(
double
)
GetValue
(
_isColumnDefinition
?
_isColumnDefinition
?
ColumnDefinition
.
MinWidthProperty
:
ColumnDefinition
.
MinWidthProperty
:
RowDefinition
.
MinHeightProperty
);
RowDefinition
.
MinHeightProperty
);
}
}
}
}
...
@@ -504,7 +512,7 @@ private bool CheckFlagsAnd(Flags flags)
...
@@ -504,7 +512,7 @@ private bool CheckFlagsAnd(Flags flags)
private
static
void
OnSharedSizeGroupPropertyChanged
(
DependencyObject
d
,
DependencyPropertyChangedEventArgs
e
)
private
static
void
OnSharedSizeGroupPropertyChanged
(
DependencyObject
d
,
DependencyPropertyChangedEventArgs
e
)
{
{
DefinitionBase
definition
=
(
DefinitionBase
)
d
;
DefinitionBase
definition
=
(
DefinitionBase
)
d
;
if
(
definition
.
InParentLogicalTree
)
if
(
definition
.
InParentLogicalTree
)
{
{
string
sharedSizeGroupId
=
(
string
)
e
.
NewValue
;
string
sharedSizeGroupId
=
(
string
)
e
.
NewValue
;
...
@@ -516,13 +524,13 @@ private static void OnSharedSizeGroupPropertyChanged(DependencyObject d, Depende
...
@@ -516,13 +524,13 @@ private static void OnSharedSizeGroupPropertyChanged(DependencyObject d, Depende
definition
.
_sharedState
.
RemoveMember
(
definition
);
definition
.
_sharedState
.
RemoveMember
(
definition
);
definition
.
_sharedState
=
null
;
definition
.
_sharedState
=
null
;
}
}
if
((
definition
.
_sharedState
==
null
)
&&
(
sharedSizeGroupId
!=
null
))
if
((
definition
.
_sharedState
==
null
)
&&
(
sharedSizeGroupId
!=
null
))
{
{
SharedSizeScope
privateSharedSizeScope
=
definition
.
PrivateSharedSizeScope
;
SharedSizeScope
privateSharedSizeScope
=
definition
.
PrivateSharedSizeScope
;
if
(
privateSharedSizeScope
!=
null
)
if
(
privateSharedSizeScope
!=
null
)
{
{
// if definition is not registered and both: shared size group id AND private shared scope
// if definition is not registered and both: shared size group id AND private shared scope
// are available, then register definition.
// are available, then register definition.
definition
.
_sharedState
=
privateSharedSizeScope
.
EnsureSharedState
(
sharedSizeGroupId
);
definition
.
_sharedState
=
privateSharedSizeScope
.
EnsureSharedState
(
sharedSizeGroupId
);
definition
.
_sharedState
.
AddMember
(
definition
);
definition
.
_sharedState
.
AddMember
(
definition
);
...
@@ -604,7 +612,7 @@ private static void OnPrivateSharedSizeScopePropertyChanged(DependencyObject d,
...
@@ -604,7 +612,7 @@ private static void OnPrivateSharedSizeScopePropertyChanged(DependencyObject d,
string
sharedSizeGroup
=
definition
.
SharedSizeGroup
;
string
sharedSizeGroup
=
definition
.
SharedSizeGroup
;
if
(
sharedSizeGroup
!=
null
)
if
(
sharedSizeGroup
!=
null
)
{
{
// if definition is not registered and both: shared size group id AND private shared scope
// if definition is not registered and both: shared size group id AND private shared scope
// are available, then register definition.
// are available, then register definition.
definition
.
_sharedState
=
privateSharedSizeScope
.
EnsureSharedState
(
definition
.
SharedSizeGroup
);
definition
.
_sharedState
=
privateSharedSizeScope
.
EnsureSharedState
(
definition
.
SharedSizeGroup
);
definition
.
_sharedState
.
AddMember
(
definition
);
definition
.
_sharedState
.
AddMember
(
definition
);
...
@@ -670,7 +678,7 @@ private bool LayoutWasUpdated
...
@@ -670,7 +678,7 @@ private bool LayoutWasUpdated
private
double
_offset
;
// offset of the DefinitionBase from left / top corner (assuming LTR case)
private
double
_offset
;
// offset of the DefinitionBase from left / top corner (assuming LTR case)
private
SharedSizeState
_sharedState
;
// reference to shared state object this instance is registered with
private
SharedSizeState
_sharedState
;
// reference to shared state object this instance is registered with
internal
const
bool
ThisIsColumnDefinition
=
true
;
internal
const
bool
ThisIsColumnDefinition
=
true
;
internal
const
bool
ThisIsRowDefinition
=
false
;
internal
const
bool
ThisIsRowDefinition
=
false
;
...
@@ -872,7 +880,7 @@ private void OnLayoutUpdated(object sender, EventArgs e)
...
@@ -872,7 +880,7 @@ private void OnLayoutUpdated(object sender, EventArgs e)
// accumulate min size of all participating definitions
// accumulate min size of all participating definitions
for
(
int
i
=
0
,
count
=
_registry
.
Count
;
i
<
count
;
++
i
)
for
(
int
i
=
0
,
count
=
_registry
.
Count
;
i
<
count
;
++
i
)
{
{
sharedMinSize
=
Math
.
Max
(
sharedMinSize
,
_registry
[
i
].
M
inSize
);
sharedMinSize
=
Math
.
Max
(
sharedMinSize
,
_registry
[
i
].
_m
inSize
);
}
}
bool
sharedMinSizeChanged
=
!
DoubleUtil
.
AreClose
(
_minSize
,
sharedMinSize
);
bool
sharedMinSizeChanged
=
!
DoubleUtil
.
AreClose
(
_minSize
,
sharedMinSize
);
...
@@ -882,31 +890,65 @@ private void OnLayoutUpdated(object sender, EventArgs e)
...
@@ -882,31 +890,65 @@ private void OnLayoutUpdated(object sender, EventArgs e)
{
{
DefinitionBase
definitionBase
=
_registry
[
i
];
DefinitionBase
definitionBase
=
_registry
[
i
];
if
(
sharedMinSizeChanged
||
definitionBase
.
LayoutWasUpdated
)
// we'll set d.UseSharedMinimum to maintain the invariant:
// d.UseSharedMinimum iff d._minSize < this.MinSize
// i.e. iff d is not a "long-pole" definition.
//
// Measure/Arrange of d's Grid uses d._minSize for long-pole
// definitions, and max(d._minSize, shared size) for
// short-pole definitions. This distinction allows us to react
// to changes in "long-pole-ness" more efficiently and correctly,
// by avoiding remeasures when a long-pole definition changes.
bool
useSharedMinimum
=
!
DoubleUtil
.
AreClose
(
definitionBase
.
_minSize
,
sharedMinSize
);
// before doing that, determine whether d's Grid needs to be remeasured.
// It's important _not_ to remeasure if the last measure is still
// valid, otherwise infinite loops are possible
bool
measureIsValid
;
if
(!
definitionBase
.
UseSharedMinimum
)
{
{
// if definition's min size is different, then need to re-measure
// d was a long-pole. measure is valid iff it's still a long-pole,
if
(!
DoubleUtil
.
AreClose
(
sharedMinSize
,
definitionBase
.
MinSize
))
// since previous measure didn't use shared size.
{
measureIsValid
=
!
useSharedMinimum
;
Grid
parentGrid
=
(
Grid
)
definitionBase
.
Parent
;
}
parentGrid
.
InvalidateMeasure
();
else
if
(
useSharedMinimum
)
definitionBase
.
UseSharedMinimum
=
true
;
{
}
// d was a short-pole, and still is. measure is valid
else
// iff the shared size didn't change
{
measureIsValid
=
!
sharedMinSizeChanged
;
definitionBase
.
UseSharedMinimum
=
false
;
}
else
// if measure is valid then also need to check arrange.
{
// Note: definitionBase.SizeCache is volatile but at this point
// d was a short-pole, but is now a long-pole. This can
// it contains up-to-date final size
// happen in several ways:
if
(!
DoubleUtil
.
AreClose
(
sharedMinSize
,
definitionBase
.
SizeCache
))
// a. d's minSize increased to or past the old shared size
{
// b. other long-pole definitions decreased, leaving
Grid
parentGrid
=
(
Grid
)
definitionBase
.
Parent
;
// d as the new winner
parentGrid
.
InvalidateArrange
();
// In the former case, the measure is valid - it used
}
// d's new larger minSize. In the latter case, the
}
// measure is invalid - it used the old shared size,
// which is larger than d's (possibly changed) minSize
measureIsValid
=
(
definitionBase
.
LayoutWasUpdated
&&
DoubleUtil
.
GreaterThanOrClose
(
definitionBase
.
_minSize
,
this
.
MinSize
));
}
definitionBase
.
LayoutWasUpdated
=
false
;
if
(!
measureIsValid
)
{
Grid
parentGrid
=
(
Grid
)
definitionBase
.
Parent
;
parentGrid
.
InvalidateMeasure
();
}
else
if
(!
DoubleUtil
.
AreClose
(
sharedMinSize
,
definitionBase
.
SizeCache
))
{
// if measure is valid then also need to check arrange.
// Note: definitionBase.SizeCache is volatile but at this point
// it contains up-to-date final size
Grid
parentGrid
=
(
Grid
)
definitionBase
.
Parent
;
parentGrid
.
InvalidateArrange
();
}
}
// now we can restore the invariant, and clear the layout flag
definitionBase
.
UseSharedMinimum
=
useSharedMinimum
;
definitionBase
.
LayoutWasUpdated
=
false
;
}
}
_minSize
=
sharedMinSize
;
_minSize
=
sharedMinSize
;
...
@@ -916,7 +958,7 @@ private void OnLayoutUpdated(object sender, EventArgs e)
...
@@ -916,7 +958,7 @@ private void OnLayoutUpdated(object sender, EventArgs e)
_broadcastInvalidation
=
true
;
_broadcastInvalidation
=
true
;
}
}
private
readonly
SharedSizeScope
_sharedSizeScope
;
// the scope this state belongs to
private
readonly
SharedSizeScope
_sharedSizeScope
;
// the scope this state belongs to
private
readonly
string
_sharedSizeGroupId
;
// Id of the shared size group this object is servicing
private
readonly
string
_sharedSizeGroupId
;
// Id of the shared size group this object is servicing
private
readonly
List
<
DefinitionBase
>
_registry
;
// registry of participating definitions
private
readonly
List
<
DefinitionBase
>
_registry
;
// registry of participating definitions
...
...
src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/Grid.cs
浏览文件 @
48258a02
...
@@ -1178,11 +1178,11 @@ private double[] CacheMinSizes(int cellsHead, bool isRows)
...
@@ -1178,11 +1178,11 @@ private double[] CacheMinSizes(int cellsHead, bool isRows)
{
{
if
(
isRows
)
if
(
isRows
)
{
{
minSizes
[
PrivateCells
[
i
].
RowIndex
]
=
DefinitionsV
[
PrivateCells
[
i
].
RowIndex
].
MinSize
;
minSizes
[
PrivateCells
[
i
].
RowIndex
]
=
DefinitionsV
[
PrivateCells
[
i
].
RowIndex
].
Raw
MinSize
;
}
}
else
else
{
{
minSizes
[
PrivateCells
[
i
].
ColumnIndex
]
=
DefinitionsU
[
PrivateCells
[
i
].
ColumnIndex
].
MinSize
;
minSizes
[
PrivateCells
[
i
].
ColumnIndex
]
=
DefinitionsU
[
PrivateCells
[
i
].
ColumnIndex
].
Raw
MinSize
;
}
}
i
=
PrivateCells
[
i
].
Next
;
i
=
PrivateCells
[
i
].
Next
;
...
...
src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/ItemsControl.cs
浏览文件 @
48258a02
...
@@ -60,7 +60,7 @@ public ItemsControl() : base()
...
@@ -60,7 +60,7 @@ public ItemsControl() : base()
static
ItemsControl
()
static
ItemsControl
()
{
{
// Define default style in code instead of in theme files.
// Define default style in code instead of in theme files.
DefaultStyleKeyProperty
.
OverrideMetadata
(
typeof
(
ItemsControl
),
new
FrameworkPropertyMetadata
(
typeof
(
ItemsControl
)));
DefaultStyleKeyProperty
.
OverrideMetadata
(
typeof
(
ItemsControl
),
new
FrameworkPropertyMetadata
(
typeof
(
ItemsControl
)));
_dType
=
DependencyObjectType
.
FromSystemTypeInternal
(
typeof
(
ItemsControl
));
_dType
=
DependencyObjectType
.
FromSystemTypeInternal
(
typeof
(
ItemsControl
));
EventManager
.
RegisterClassHandler
(
typeof
(
ItemsControl
),
Keyboard
.
GotKeyboardFocusEvent
,
new
KeyboardFocusChangedEventHandler
(
OnGotFocus
));
EventManager
.
RegisterClassHandler
(
typeof
(
ItemsControl
),
Keyboard
.
GotKeyboardFocusEvent
,
new
KeyboardFocusChangedEventHandler
(
OnGotFocus
));
...
@@ -3011,7 +3011,7 @@ private bool IsOnCurrentPage(FrameworkElement viewPort, FrameworkElement element
...
@@ -3011,7 +3011,7 @@ private bool IsOnCurrentPage(FrameworkElement viewPort, FrameworkElement element
Rect
viewPortBounds
=
new
Rect
(
new
Point
(),
viewPort
.
RenderSize
);
Rect
viewPortBounds
=
new
Rect
(
new
Point
(),
viewPort
.
RenderSize
);
Rect
elementBounds
=
new
Rect
(
new
Point
(),
element
.
RenderSize
);
Rect
elementBounds
=
new
Rect
(
new
Point
(),
element
.
RenderSize
);
elementBounds
=
element
.
TransformToAncestor
(
viewPort
).
TransformBounds
(
elementBounds
);
elementBounds
=
CorrectCatastrophicCancellation
(
element
.
TransformToAncestor
(
viewPort
)
).
TransformBounds
(
elementBounds
);
bool
northSouth
=
(
axis
==
FocusNavigationDirection
.
Up
||
axis
==
FocusNavigationDirection
.
Down
);
bool
northSouth
=
(
axis
==
FocusNavigationDirection
.
Up
||
axis
==
FocusNavigationDirection
.
Down
);
bool
eastWest
=
(
axis
==
FocusNavigationDirection
.
Left
||
axis
==
FocusNavigationDirection
.
Right
);
bool
eastWest
=
(
axis
==
FocusNavigationDirection
.
Left
||
axis
==
FocusNavigationDirection
.
Right
);
...
@@ -3078,6 +3078,46 @@ private bool IsOnCurrentPage(FrameworkElement viewPort, FrameworkElement element
...
@@ -3078,6 +3078,46 @@ private bool IsOnCurrentPage(FrameworkElement viewPort, FrameworkElement element
return
ElementViewportPosition
.
None
;
return
ElementViewportPosition
.
None
;
}
}
// in large virtualized hierarchical lists (TreeView or grouping), the transform
// returned by element.TransformToAncestor(viewport) is vulnerable to catastrophic
// cancellation. If element is at the top of the viewport, but embedded in
// layers of the hierarchy, the contributions of the intermediate elements add
// up to a large positive number which should exactly cancel out the large
// negative offset of the viewport's direct child to produce net offset of 0.0.
// But floating-point drift while accumulating the intermediate offsets and
// catastrophic cancellation in the last step may produce a very small
// non-zero number instead (e.g. -0.0000000000006548). This can lead to
// infinite loops and incorrect decisions in layout.
// To mitigate this problem, replace near-zero offsets with zero.
private
static
GeneralTransform
CorrectCatastrophicCancellation
(
GeneralTransform
transform
)
{
MatrixTransform
matrixTransform
=
transform
as
MatrixTransform
;
if
(
matrixTransform
!=
null
)
{
bool
needNewTransform
=
false
;
Matrix
matrix
=
matrixTransform
.
Matrix
;
if
(
matrix
.
OffsetX
!=
0.0
&&
LayoutDoubleUtil
.
AreClose
(
matrix
.
OffsetX
,
0.0
))
{
matrix
.
OffsetX
=
0.0
;
needNewTransform
=
true
;
}
if
(
matrix
.
OffsetY
!=
0.0
&&
LayoutDoubleUtil
.
AreClose
(
matrix
.
OffsetY
,
0.0
))
{
matrix
.
OffsetY
=
0.0
;
needNewTransform
=
true
;
}
if
(
needNewTransform
)
{
transform
=
new
MatrixTransform
(
matrix
);
}
}
return
transform
;
}
private
static
bool
ElementIntersectsViewport
(
Rect
viewportRect
,
Rect
elementRect
)
private
static
bool
ElementIntersectsViewport
(
Rect
viewportRect
,
Rect
elementRect
)
{
{
if
(
viewportRect
.
IsEmpty
||
elementRect
.
IsEmpty
)
if
(
viewportRect
.
IsEmpty
||
elementRect
.
IsEmpty
)
...
...
src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/VirtualizingStackPanel.cs
浏览文件 @
48258a02
...
@@ -1237,7 +1237,7 @@ private void ClearAnchorInformation(bool shouldAbort)
...
@@ -1237,7 +1237,7 @@ private void ClearAnchorInformation(bool shouldAbort)
// don't delve into non-VSP panels - the result is
// don't delve into non-VSP panels - the result is
// inconsistent with FindScrollOffset, and causes
// inconsistent with FindScrollOffset, and causes
// infinite loops
// infinite loops
innerPanel = innerPanel as VirtualizingStackPanel;
innerPanel = innerPanel as VirtualizingStackPanel;
if (innerPanel != null && innerPanel.IsVisible)
if (innerPanel != null && innerPanel.IsVisible)
...
@@ -2279,7 +2279,7 @@ private Size RealMeasureOverride(Size constraint)
...
@@ -2279,7 +2279,7 @@ private Size RealMeasureOverride(Size constraint)
// final size (e.g. when content arrives via bindings
// final size (e.g. when content arrives via bindings
// that don't activate until after layout), as it
// that don't activate until after layout), as it
// causes a lot of extra measure passes, where "a lot"
// causes a lot of extra measure passes, where "a lot"
// can be as bad as "infinite".
// can be as bad as "infinite".
//
//
// To avoid this waste, exclude a proportional part
// To avoid this waste, exclude a proportional part
// of the normal viewport as well.
// of the normal viewport as well.
...
@@ -2812,7 +2812,7 @@ private Size RealMeasureOverride(Size constraint)
...
@@ -2812,7 +2812,7 @@ private Size RealMeasureOverride(Size constraint)
// If there were a collection changed between the BringIndexIntoView call
// If there were a collection changed between the BringIndexIntoView call
// and the current Measure then it is possible that the item for the
// and the current Measure then it is possible that the item for the
// _bringIntoViewContainer has been removed from the collection and so
// _bringIntoViewContainer has been removed from the collection and so
// has the container. We need to guard against this scenario.
// has the container. We need to guard against this scenario.
_bringIntoViewContainer = null;
_bringIntoViewContainer = null;
}
}
else
else
...
@@ -4609,7 +4609,7 @@ private void ClearIsScrollActive()
...
@@ -4609,7 +4609,7 @@ private void ClearIsScrollActive()
// if the viewport is empty in the scrolling direction, force the
// if the viewport is empty in the scrolling direction, force the
// cache to be empty also. This avoids an infinite loop re- and
// cache to be empty also. This avoids an infinite loop re- and
// de-virtualizing the last item
// de-virtualizing the last item
if (IsViewportEmpty(isHorizontal, viewport))
if (IsViewportEmpty(isHorizontal, viewport))
{
{
cacheLength = new VirtualizationCacheLength(0, 0);
cacheLength = new VirtualizationCacheLength(0, 0);
...
@@ -5550,7 +5550,7 @@ private void CoerceScrollingViewportOffset(ref Rect viewport, Size extent, bool
...
@@ -5550,7 +5550,7 @@ private void CoerceScrollingViewportOffset(ref Rect viewport, Size extent, bool
bool areContainersUniformlySized,
bool areContainersUniformlySized,
double uniformOrAverageContainerSize)
double uniformOrAverageContainerSize)
{
{
if (firstContainer == null)
if (firstContainer == null
|| IsViewportEmpty(isHorizontal, viewport)
)
{
{
return -1.0; // undefined if no children in view
return -1.0; // undefined if no children in view
}
}
...
@@ -6149,7 +6149,7 @@ private void CoerceScrollingViewportOffset(ref Rect viewport, Size extent, bool
...
@@ -6149,7 +6149,7 @@ private void CoerceScrollingViewportOffset(ref Rect viewport, Size extent, bool
// into non-uniform mode just because the pixel heights are different,
// into non-uniform mode just because the pixel heights are different,
// and a good reason to avoid it: it requires looping through all
// and a good reason to avoid it: it requires looping through all
// containers to compute an average size, which breaks third-party's
// containers to compute an average size, which breaks third-party's
// attempts to do data virtualization
// attempts to do data virtualization
bool ignoreContainerPixelSize = IsPixelBased || (IsScrolling && !hasVirtualizingChildren);
bool ignoreContainerPixelSize = IsPixelBased || (IsScrolling && !hasVirtualizingChildren);
if (isHorizontal)
if (isHorizontal)
...
@@ -9526,7 +9526,7 @@ private void OnScrollChange()
...
@@ -9526,7 +9526,7 @@ private void OnScrollChange()
//
//
// We do not want the cache measure pass to affect the visibility
// We do not want the cache measure pass to affect the visibility
// of the scrollbars because this makes bad user experience and
// of the scrollbars because this makes bad user experience and
// is also the source of scrolling bugs.
// is also the source of scrolling bugs.
//
//
stackPixelSize.Width = _scrollData._extent.Width;
stackPixelSize.Width = _scrollData._extent.Width;
...
@@ -9641,7 +9641,7 @@ private void OnScrollChange()
...
@@ -9641,7 +9641,7 @@ private void OnScrollChange()
offsetForScrollViewerRemeasure.X = newOffset;
offsetForScrollViewerRemeasure.X = newOffset;
// adjust the persisted viewports too, in case the next use
// adjust the persisted viewports too, in case the next use
// occurs before a measure, e.g. adding item to Items
// occurs before a measure, e.g. adding item to Items
_viewport.X = newOffset;
_viewport.X = newOffset;
_extendedViewport.X += delta;
_extendedViewport.X += delta;
...
@@ -9666,7 +9666,7 @@ private void OnScrollChange()
...
@@ -9666,7 +9666,7 @@ private void OnScrollChange()
offsetForScrollViewerRemeasure.Y = newOffset;
offsetForScrollViewerRemeasure.Y = newOffset;
// adjust the persisted viewports too, in case the next use
// adjust the persisted viewports too, in case the next use
// occurs before a measure, e.g. adding item to Items
// occurs before a measure, e.g. adding item to Items
_viewport.Y = newOffset;
_viewport.Y = newOffset;
_extendedViewport.Y += delta;
_extendedViewport.Y += delta;
...
...
src/Microsoft.DotNet.Wpf/src/System.Windows.Controls.Ribbon/Microsoft/Windows/Controls/Ribbon/RibbonHelper.cs
浏览文件 @
48258a02
// Licensed to the .NET Foundation under one or more agreements.
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// See the LICENSE file in the project root for more information.
#if RIBBON_IN_FRAMEWORK
#if RIBBON_IN_FRAMEWORK
namespace
System.Windows.Controls.Ribbon
namespace
System.Windows.Controls.Ribbon
...
@@ -1059,7 +1059,11 @@ public static bool IsOurWindow(IntPtr hwnd, DependencyObject element)
...
@@ -1059,7 +1059,11 @@ public static bool IsOurWindow(IntPtr hwnd, DependencyObject element)
// popups when both active source and current captured is
// popups when both active source and current captured is
// null due to clicking some where else should be handled by
// null due to clicking some where else should be handled by
// click through event handler.
// click through event handler.
ReacquireCapture
(
targetCapture
,
targetFocus
);
if
(!
ReacquireCapture
(
targetCapture
,
targetFocus
))
{
// call the setter if we couldn't reacquire capture
setter
(
false
);
}
e
.
Handled
=
true
;
e
.
Handled
=
true
;
}
}
else
else
...
@@ -1078,7 +1082,11 @@ public static bool IsOurWindow(IntPtr hwnd, DependencyObject element)
...
@@ -1078,7 +1082,11 @@ public static bool IsOurWindow(IntPtr hwnd, DependencyObject element)
{
{
// If a descendant of targetCapture is losing capture
// If a descendant of targetCapture is losing capture
// then take capture on targetCapture
// then take capture on targetCapture
ReacquireCapture
(
targetCapture
,
targetFocus
);
if
(!
ReacquireCapture
(
targetCapture
,
targetFocus
))
{
// call the setter if we couldn't reacquire capture
setter
(
false
);
}
e
.
Handled
=
true
;
e
.
Handled
=
true
;
}
}
else
if
(!
IsCaptureInSubtree
(
targetCapture
))
else
if
(!
IsCaptureInSubtree
(
targetCapture
))
...
@@ -1092,13 +1100,14 @@ public static bool IsOurWindow(IntPtr hwnd, DependencyObject element)
...
@@ -1092,13 +1100,14 @@ public static bool IsOurWindow(IntPtr hwnd, DependencyObject element)
}
}
}
}
private
static
void
ReacquireCapture
(
UIElement
targetCapture
,
UIElement
targetFocus
)
private
static
bool
ReacquireCapture
(
UIElement
targetCapture
,
UIElement
targetFocus
)
{
{
Mouse
.
Capture
(
targetCapture
,
CaptureMode
.
SubTree
);
bool
success
=
Mouse
.
Capture
(
targetCapture
,
CaptureMode
.
SubTree
);
if
(
targetFocus
!=
null
&&
!
targetFocus
.
IsKeyboardFocusWithin
)
if
(
success
&&
targetFocus
!=
null
&&
!
targetFocus
.
IsKeyboardFocusWithin
)
{
{
targetFocus
.
Focus
();
targetFocus
.
Focus
();
}
}
return
success
;
}
}
public
static
bool
IsMousePhysicallyOver
(
UIElement
element
)
public
static
bool
IsMousePhysicallyOver
(
UIElement
element
)
...
...
src/Microsoft.DotNet.Wpf/src/System.Windows.Controls.Ribbon/Microsoft/Windows/Controls/Ribbon/RibbonMenuButton.cs
浏览文件 @
48258a02
// Licensed to the .NET Foundation under one or more agreements.
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// See the LICENSE file in the project root for more information.
#if RIBBON_IN_FRAMEWORK
#if RIBBON_IN_FRAMEWORK
namespace
System.Windows.Controls.Ribbon
namespace
System.Windows.Controls.Ribbon
...
@@ -30,11 +30,11 @@ namespace Microsoft.Windows.Controls.Ribbon
...
@@ -30,11 +30,11 @@ namespace Microsoft.Windows.Controls.Ribbon
using
Microsoft.Windows.Controls.Ribbon.Primitives
;
using
Microsoft.Windows.Controls.Ribbon.Primitives
;
#endif
#endif
using
MS.Internal
;
using
MS.Internal
;
#
endregion
#
endregion
/// <summary>
/// <summary>
/// RibbonMenuButton is an ItemsControl which on clicking displays a Menu. Its Items could be either RibbonMenuItems, RibbonGallerys or Separators.
/// RibbonMenuButton is an ItemsControl which on clicking displays a Menu. Its Items could be either RibbonMenuItems, RibbonGallerys or Separators.
/// </summary>
/// </summary>
[
TemplatePart
(
Name
=
RibbonMenuButton
.
ResizeThumbTemplatePartName
,
Type
=
typeof
(
Thumb
))]
[
TemplatePart
(
Name
=
RibbonMenuButton
.
ResizeThumbTemplatePartName
,
Type
=
typeof
(
Thumb
))]
[
TemplatePart
(
Name
=
RibbonMenuButton
.
ToggleButtonTemplatePartName
,
Type
=
typeof
(
RibbonToggleButton
))]
[
TemplatePart
(
Name
=
RibbonMenuButton
.
ToggleButtonTemplatePartName
,
Type
=
typeof
(
RibbonToggleButton
))]
...
@@ -592,9 +592,9 @@ protected override void ClearContainerForItemOverride(DependencyObject element,
...
@@ -592,9 +592,9 @@ protected override void ClearContainerForItemOverride(DependencyObject element,
{
{
base
.
ClearContainerForItemOverride
(
element
,
item
);
base
.
ClearContainerForItemOverride
(
element
,
item
);
// RibbonComboBox containers are pre-generated.
// RibbonComboBox containers are pre-generated.
// When dropdown is opened for the first time ever and ItemContainerGenerator
// When dropdown is opened for the first time ever and ItemContainerGenerator
// is hooked up to ItemsPanel, existing containers are cleared, causing _galleryCount to be -ve.
// is hooked up to ItemsPanel, existing containers are cleared, causing _galleryCount to be -ve.
// Hence the check for _galleryCount > 0
// Hence the check for _galleryCount > 0
if
(
element
is
RibbonGallery
&&
_galleryCount
>
0
)
if
(
element
is
RibbonGallery
&&
_galleryCount
>
0
)
{
{
...
@@ -672,7 +672,7 @@ protected override bool HandlesScrolling
...
@@ -672,7 +672,7 @@ protected override bool HandlesScrolling
public
override
void
OnApplyTemplate
()
public
override
void
OnApplyTemplate
()
{
{
// If a new template has just been generated then
// If a new template has just been generated then
// be sure to clear any stale ItemsHost references
// be sure to clear any stale ItemsHost references
if
(
InternalItemsHost
!=
null
&&
!
this
.
IsAncestorOf
(
InternalItemsHost
))
if
(
InternalItemsHost
!=
null
&&
!
this
.
IsAncestorOf
(
InternalItemsHost
))
{
{
...
@@ -824,7 +824,7 @@ internal void OnNavigationKeyDown(KeyEventArgs e)
...
@@ -824,7 +824,7 @@ internal void OnNavigationKeyDown(KeyEventArgs e)
{
{
if
(
itemNavigateFromCurrentFocused
)
if
(
itemNavigateFromCurrentFocused
)
{
{
// event could have bubbled up from MenuItem
// event could have bubbled up from MenuItem
// when it could not navigate to the next item (for eg. gallery)
// when it could not navigate to the next item (for eg. gallery)
handled
=
RibbonHelper
.
NavigateToNextMenuItemOrGallery
(
this
,
focusedIndex
,
BringIndexIntoView
);
handled
=
RibbonHelper
.
NavigateToNextMenuItemOrGallery
(
this
,
focusedIndex
,
BringIndexIntoView
);
}
}
...
@@ -841,7 +841,7 @@ internal void OnNavigationKeyDown(KeyEventArgs e)
...
@@ -841,7 +841,7 @@ internal void OnNavigationKeyDown(KeyEventArgs e)
{
{
if
(
itemNavigateFromCurrentFocused
)
if
(
itemNavigateFromCurrentFocused
)
{
{
// event could have bubbled up from MenuItem
// event could have bubbled up from MenuItem
// when it could not navigate to the previous item (for eg. gallery)
// when it could not navigate to the previous item (for eg. gallery)
handled
=
RibbonHelper
.
NavigateToPreviousMenuItemOrGallery
(
this
,
focusedIndex
,
BringIndexIntoView
);
handled
=
RibbonHelper
.
NavigateToPreviousMenuItemOrGallery
(
this
,
focusedIndex
,
BringIndexIntoView
);
}
}
...
@@ -1015,7 +1015,7 @@ void OnPopupResize(object sender, DragDeltaEventArgs e)
...
@@ -1015,7 +1015,7 @@ void OnPopupResize(object sender, DragDeltaEventArgs e)
}
}
/// <summary>
/// <summary>
/// Called from UIA Peers.
/// Called from UIA Peers.
/// </summary>
/// </summary>
/// <param name="newWidth"></param>
/// <param name="newWidth"></param>
/// <param name="newHeight"></param>
/// <param name="newHeight"></param>
...
@@ -1079,11 +1079,11 @@ private static void OnIsDropDownOpenChanged(DependencyObject d, DependencyProper
...
@@ -1079,11 +1079,11 @@ private static void OnIsDropDownOpenChanged(DependencyObject d, DependencyProper
internal
virtual
void
OnIsDropDownOpenChanged
(
DependencyPropertyChangedEventArgs
e
)
internal
virtual
void
OnIsDropDownOpenChanged
(
DependencyPropertyChangedEventArgs
e
)
{
{
// If the drop down is closed due to
// If the drop down is closed due to
// an action of context menu or if the
// an action of context menu or if the
// ContextMenu for a parent (Ribbon)
// ContextMenu for a parent (Ribbon)
// was opened by right clicking this
// was opened by right clicking this
// RibbonMenuButton (RibbonApplicationMenu)
// RibbonMenuButton (RibbonApplicationMenu)
// then ContextMenuClosed event is never raised.
// then ContextMenuClosed event is never raised.
// Hence reset the flag.
// Hence reset the flag.
InContextMenu
=
false
;
InContextMenu
=
false
;
...
@@ -1098,7 +1098,7 @@ internal virtual void OnIsDropDownOpenChanged(DependencyPropertyChangedEventArgs
...
@@ -1098,7 +1098,7 @@ internal virtual void OnIsDropDownOpenChanged(DependencyPropertyChangedEventArgs
BaseOnIsKeyboardFocusWithin
();
BaseOnIsKeyboardFocusWithin
();
OnDropDownOpened
(
EventArgs
.
Empty
);
OnDropDownOpened
(
EventArgs
.
Empty
);
// Clear local values
// Clear local values
// so that when DropDown opens it shows in it original size and PlacementMode
// so that when DropDown opens it shows in it original size and PlacementMode
RibbonDropDownHelper
.
ClearLocalValues
(
_itemsPresenter
,
_popup
);
RibbonDropDownHelper
.
ClearLocalValues
(
_itemsPresenter
,
_popup
);
...
@@ -1110,7 +1110,7 @@ internal virtual void OnIsDropDownOpenChanged(DependencyPropertyChangedEventArgs
...
@@ -1110,7 +1110,7 @@ internal virtual void OnIsDropDownOpenChanged(DependencyPropertyChangedEventArgs
}
}
// IsDropDownPositionedAbove is updated asynchronously.
// IsDropDownPositionedAbove is updated asynchronously.
// As a result the resize thumb would change position and we could see a visual artifact of this change after Popup opens.
// As a result the resize thumb would change position and we could see a visual artifact of this change after Popup opens.
Dispatcher
.
BeginInvoke
(
new
DispatcherOperationCallback
(
UpdateDropDownPosition
),
DispatcherPriority
.
Loaded
,
new
object
[]
{
null
});
Dispatcher
.
BeginInvoke
(
new
DispatcherOperationCallback
(
UpdateDropDownPosition
),
DispatcherPriority
.
Loaded
,
new
object
[]
{
null
});
}
}
else
else
...
@@ -1200,15 +1200,15 @@ private static void OnHasGalleryChanged(DependencyObject d, DependencyPropertyCh
...
@@ -1200,15 +1200,15 @@ private static void OnHasGalleryChanged(DependencyObject d, DependencyPropertyCh
RibbonHelper
.
SetDropDownHeight
(
menuButton
.
_itemsPresenter
,
(
bool
)
e
.
NewValue
,
menuButton
.
DropDownHeight
);
RibbonHelper
.
SetDropDownHeight
(
menuButton
.
_itemsPresenter
,
(
bool
)
e
.
NewValue
,
menuButton
.
DropDownHeight
);
}
}
// Note that when the HasGallery property changes we expect that the
// Note that when the HasGallery property changes we expect that the
// VerticalScrollBarVisibilityProperty for the primary _submenuScrollViewer
// VerticalScrollBarVisibilityProperty for the primary _submenuScrollViewer
// that hosts galleries and/or menu items is updated. Even though this
// that hosts galleries and/or menu items is updated. Even though this
// property is marked AffectsMeasure it doesn't exactly cause the additonal
// property is marked AffectsMeasure it doesn't exactly cause the additonal
// call to ScrollViewer.MeasureOverrider because HasGallery is typically
// call to ScrollViewer.MeasureOverrider because HasGallery is typically
// updated during a Measure pass when PrepareContainerForItemOverride is
// updated during a Measure pass when PrepareContainerForItemOverride is
// called and thus the invalidation noops. To ensure that we call
// called and thus the invalidation noops. To ensure that we call
// ScrollViewer.MeasureOverride another time after this property has been
// ScrollViewer.MeasureOverride another time after this property has been
// updated, we need to wait for the current Measure pass to subside and
// updated, we need to wait for the current Measure pass to subside and
// then InvalidateMeasure on the _submenuScrollViewer.
// then InvalidateMeasure on the _submenuScrollViewer.
RibbonHelper
.
InvalidateScrollBarVisibility
(
menuButton
.
_submenuScrollViewer
);
RibbonHelper
.
InvalidateScrollBarVisibility
(
menuButton
.
_submenuScrollViewer
);
...
@@ -1281,7 +1281,7 @@ private object UpdateDropDownPosition(object arg)
...
@@ -1281,7 +1281,7 @@ private object UpdateDropDownPosition(object arg)
// Cache the screen bounds of the monitor in which the dropdown is opened
// Cache the screen bounds of the monitor in which the dropdown is opened
_screenBounds
=
RibbonDropDownHelper
.
GetScreenBounds
(
_itemsPresenter
,
_popup
);
_screenBounds
=
RibbonDropDownHelper
.
GetScreenBounds
(
_itemsPresenter
,
_popup
);
// Also cache the PopupRoot if opened for the first time
// Also cache the PopupRoot if opened for the first time
if
(
_popupRoot
==
null
&&
_itemsPresenter
!=
null
)
if
(
_popupRoot
==
null
&&
_itemsPresenter
!=
null
)
{
{
...
@@ -1394,7 +1394,7 @@ internal RibbonToggleButton PartToggleButton
...
@@ -1394,7 +1394,7 @@ internal RibbonToggleButton PartToggleButton
}
}
/// <summary>
/// <summary>
/// base exits MenuMode on any Mouse clicks. We want to prevent that.
/// base exits MenuMode on any Mouse clicks. We want to prevent that.
/// </summary>
/// </summary>
/// <param name="e"></param>
/// <param name="e"></param>
protected
override
void
HandleMouseButton
(
MouseButtonEventArgs
e
)
protected
override
void
HandleMouseButton
(
MouseButtonEventArgs
e
)
...
@@ -1471,9 +1471,9 @@ protected override void OnPreviewMouseDown(MouseButtonEventArgs e)
...
@@ -1471,9 +1471,9 @@ protected override void OnPreviewMouseDown(MouseButtonEventArgs e)
protected
override
void
OnIsKeyboardFocusWithinChanged
(
DependencyPropertyChangedEventArgs
e
)
protected
override
void
OnIsKeyboardFocusWithinChanged
(
DependencyPropertyChangedEventArgs
e
)
{
{
// If IsKeyboardFocusWithin has become true, then do not
// If IsKeyboardFocusWithin has become true, then do not
// call base.OnIsKeyboardFocusWithinChanged right away.
// call base.OnIsKeyboardFocusWithinChanged right away.
// Defer the bases call until DropDown gets opened or
// Defer the bases call until DropDown gets opened or
// one of the descendants get focus.
// one of the descendants get focus.
if
(!
IsKeyboardFocusWithin
)
if
(!
IsKeyboardFocusWithin
)
{
{
...
@@ -1513,7 +1513,10 @@ private void OnGotKeyboardFocusThunk(KeyboardFocusChangedEventArgs e)
...
@@ -1513,7 +1513,10 @@ private void OnGotKeyboardFocusThunk(KeyboardFocusChangedEventArgs e)
{
{
// Call base.OnIsKeyboardFocusWithinChanged only if the new focus
// Call base.OnIsKeyboardFocusWithinChanged only if the new focus
// is not a direct descendant of menu button.
// is not a direct descendant of menu button.
// It's possible to get here when disabled, which can lead to a
// focus war resulting in StackOverflow. Don't start the war.
if
(
e
.
OriginalSource
!=
this
&&
if
(
e
.
OriginalSource
!=
this
&&
this
.
IsEnabled
&&
!
TreeHelper
.
IsVisualAncestorOf
(
this
,
e
.
OriginalSource
as
DependencyObject
))
!
TreeHelper
.
IsVisualAncestorOf
(
this
,
e
.
OriginalSource
as
DependencyObject
))
{
{
BaseOnIsKeyboardFocusWithin
();
BaseOnIsKeyboardFocusWithin
();
...
@@ -1528,13 +1531,19 @@ protected override void OnGotKeyboardFocus(KeyboardFocusChangedEventArgs e)
...
@@ -1528,13 +1531,19 @@ protected override void OnGotKeyboardFocus(KeyboardFocusChangedEventArgs e)
if
(
ribbonCurrentSelection
!=
null
&&
if
(
ribbonCurrentSelection
!=
null
&&
IsDropDownOpen
)
IsDropDownOpen
)
{
{
// If the drop down is open and the ribbonCurrentSelection is valid
// but still popup doesnt have focus within,
// then focus the current selection.
// It's possible to get here when disabled, or when an app explicitly
// moves focus in a GotKeyboardFocus handler called earlier in the
// bubbling route. Either of these can lead to a
// focus war resulting in StackOverflow. Don't start the war
UIElement
popupChild
=
_popup
.
TryGetChild
();
UIElement
popupChild
=
_popup
.
TryGetChild
();
if
(
popupChild
!=
null
&&
if
(
popupChild
!=
null
&&
this
.
IsEnabled
&&
this
.
IsKeyboardFocusWithin
&&
!
popupChild
.
IsKeyboardFocusWithin
)
!
popupChild
.
IsKeyboardFocusWithin
)
{
{
// If the drop down is open and the ribbonCurrentSelection is valid
// but still popup doesnt have focus within,
// then focus the current selection.
ribbonCurrentSelection
.
Focus
();
ribbonCurrentSelection
.
Focus
();
}
}
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录