小编Pet*_*iho的帖子

为什么嵌套网格中的星形大小不起作用?

考虑以下XAML:

<Grid>
  <Grid.ColumnDefinitions>
    <ColumnDefinition/>
    <ColumnDefinition Width="Auto"/>
  </Grid.ColumnDefinitions>
  <Button Content="Button" HorizontalAlignment="Left"/>
  <Grid Grid.Column="1">
    <Grid.ColumnDefinitions>
      <ColumnDefinition/>
      <ColumnDefinition/>
    </Grid.ColumnDefinitions>
    <Button Content="B" Margin="5"/>
    <Button Content="Button" Grid.Column="1" Margin="5"/>
  </Grid>
</Grid>
Run Code Online (Sandbox Code Playgroud)

在上文中,所有ColumnDefinition除了一个值,使用默认值Width,也就是"*",即"明星上浆".一个例外是包含嵌套Grid控件的列,该控件设置为"Auto".

我期望它的工作方式如下:

  • 外部Grid根据其内容的需要调整第二列的大小,然后将控件的剩余宽度分配给第一列.
  • 内部Grid将其可用空间均匀分布到两列.毕竟,它们都设置为使用星形大小,并且星形大小应该将GridLength属性(在这种情况下为宽度)设置为可用空间的加权分布.此内部的最小布局大小Grid(外部Grid计算其第二列宽度所需)是均匀分布宽度,星形大小的列的总和(即在这种情况下,是列的宽度的两倍,最广泛的内容).

但相反,嵌套网格的列宽根据计算出的每个按钮的最小大小进行设置,两个星大小的列之间没有明显的加权关系(为清晰起见,显示了网格线):

错误分布的列宽

如果我没有外部网格,它只是按预期工作,即只是使内部网格成为窗口中唯一的网格:

正确分布的列宽

两列被强制为相同的大小,当然左手按钮被拉伸以适应其包含单元格的大小(这就是我想要的......最终目标是让这两个按钮具有相同的宽度,网格列提供了完成该布局的布局.


在这个特定的例子中,我可以UniformGrid用作解决方法,强制均匀分布列宽.这就是我想要它实际看起来的样子(UniformGrid没有ShowGridLines属性,所以你只需要想象两个最右边按钮之间的假想线):

在此输入图像描述

但我真的想更全​​面地了解如何实现这一点,以便在更复杂的场景中我能够在嵌套Grid控件中使用星型大小.


似乎不知何故,被包含在另一个Grid控件的单元格中正在改变为内部Grid控件计算星形大小的方式(或者防止星形大小完全没有任何影响).但为什么会这样呢?我是否遗漏了(再次)WPF的一些深奥的布局规则,将其解释为"按设计"行为?或者这仅仅是框架中的错误?


更新:

我理解Ben的答案意味着考虑每列的最小尺寸,星形尺寸应仅分布剩余空间.但这不是人们在其他场景中看到的.

例如,如果包含内部网格的列已明确调整大小,则对内部网格的列使用星号大小会导致列的大小均匀,就像我期望的那样.

即这个XAML:

<Grid ShowGridLines="True">
  <Grid.ColumnDefinitions> …
Run Code Online (Sandbox Code Playgroud)

c# wpf

15
推荐指数
2
解决办法
2785
查看次数

编译器错误:"错误CS0307:变量'int'不能与类型参数一起使用"

如果我有以下代码:

private void Check(bool a, bool b)
{
}

private void Check(int a, int b, int c, bool flag)
{
    Check(a < b, a > (flag ? c : b - 10));
}
Run Code Online (Sandbox Code Playgroud)

我在调用时遇到编译时错误Check(int, int):

错误CS0307:变量'int'不能与类型参数一起使用

我也得到这些错误:

错误CS0118:'b'是一个变量但是像类型
错误CS0118 一样使用:'a'是一个变量但是像一个类型一样使用

为什么会出现这些错误?代码有什么问题?

.net c# compiler-errors visual-studio

13
推荐指数
1
解决办法
1003
查看次数

为什么Finalize/Destructor示例在.NET Core中不起作用?

我试图了解终结和析构函数如何在C#中工作,我试图在System.Object.Finalize示例中运行代码(代码复制粘贴,没有做出任何更改),但输出与预期的不一样,它表明析构函数是从未打电话过

代码是:

using System;
using System.Diagnostics;

public class ExampleClass
{
   Stopwatch sw;

   public ExampleClass()
   {
      sw = Stopwatch.StartNew();
      Console.WriteLine("Instantiated object");
   } 

   public void ShowDuration()
   {
      Console.WriteLine("This instance of {0} has been in existence for {1}",
                    this, sw.Elapsed);
   }

   ~ExampleClass()
   {
      Console.WriteLine("Finalizing object");
      sw.Stop();
      Console.WriteLine("This instance of {0} has been in existence for {1}",
                    this, sw.Elapsed);
   }
}

public class Demo
{
   public static void Main()
   {
      ExampleClass ex = new ExampleClass();
      ex.ShowDuration();
   }
}
Run Code Online (Sandbox Code Playgroud)

更新:

当我使用visual studio和.net framework …

.net c# destructor .net-core

13
推荐指数
1
解决办法
1819
查看次数

将字符串作为流读取而不进行复制

我在字符串中有一些数据。我有一个以流作为输入的函数。我想向我的函数提供数据,而不必将完整的字符串复制到流中。本质上我正在寻找一个可以包装字符串并从中读取的流类。

我在网上看到的唯一建议是 StringReader 它不是流,或者创建一个内存流并写入它,这意味着复制数据。我可以编写自己的流对象,但棘手的部分是处理编码,因为流以字节为单位进行处理。有没有办法在不编写新的流类的情况下做到这一点?

我正在 BizTalk 中实现管道组件。BizTalk 完全通过流处理所有内容,因此您始终将内容通过流传递给 BizTalk。BizTalk 始终会以小块的形式从小块中读取该流,因此如果我可以从流中读取 BizTalk 想要的方式,则将整个字符串复制到流中(特别是当字符串很大时)是没有意义的。

c#

10
推荐指数
2
解决办法
6048
查看次数

与异步方法有关的VoidTaskResult类型是什么?

我最近第一次使用异步(和.Net 4.5),我遇到了让我难过的东西.关于我可以在网上找到的VoidTaskResult类的信息不多,所以我来到这里是为了看看是否有任何关于发生了什么的想法.

我的代码如下所示.显然,这很简单.基本思想是调用异步的插件方法.如果它们返回Task,则异步调用没有返回值.如果他们返回Task <>,那么就有了.我们事先不知道它们是哪种类型,因此我们的想法是使用反射查看结果的类型(如果类型为Type <>,则IsGenericType为true)并使用动态类型获取值.

在我的真实代码中,我通过反射调用插件方法.我认为这不应该对我所看到的行为产生影响.

// plugin method
public Task yada()
{
 // stuff
}

public async void doYada()
{
  Task task = yada();
  await task;

  if (task.GetType().IsGenericType)
  {
    dynamic dynTask = task;
    object result = dynTask.Result;
    // do something with result
  }
}
Run Code Online (Sandbox Code Playgroud)

这适用于上面显示的插件方法.IsGenericType为false(正如预期的那样).

但是,如果稍微更改插件方法的声明,IsGenericType现在返回true并且东西中断:

public async Task yada()
{
 // stuff
}
Run Code Online (Sandbox Code Playgroud)

执行此操作时,行上会抛出以下异常(object result = dynTask.Result;):

RuntimeBinderException

如果你深入研究任务对象,它实际上似乎是类型.VoidTaskResult是线程名称空间中的私有类型,几乎没有任何内容.

VoidTaskResult任务

我尝试更改我的调用代码:

public async void doYada()
{
  Task task = yada();
  await task;

  if (task.GetType().IsGenericType)
  {
    object result = task.GetType().GetProperty("Result").GetMethod.Invoke(task, new …
Run Code Online (Sandbox Code Playgroud)

c# reflection asynchronous dynamic

9
推荐指数
1
解决办法
1257
查看次数

事件源vs原始源

我正在阅读C#WPF书和路由事件章节,事件有2个相同的属性SourceOriginalSource.我没有看到它们之间的区别:

XAML:

<Button Name="Ok" Click="Ok_Click"/>
Run Code Online (Sandbox Code Playgroud)

代码背后:

private void Ok_Click(object sender, RoutedEventArgs e)
{
        bool flag = false;
        var source = e.Source;
        var originalSource = e.OriginalSource;
        if (source == originalSource)
        {
            flag = true;
        }
}
Run Code Online (Sandbox Code Playgroud)

flag属性true在这里,有人可以解释为什么2相同的属性或在这种情况下这个属性没有影响?或者我们在哪里可以看到这个属性的用例?

c# wpf events xaml

8
推荐指数
1
解决办法
4006
查看次数

XAML无法编译,但没有任何错误消息,如果用户定义的对象是第一个资源,并且紧跟x:Array资源

我发现这个问题很奇怪,可能是一个XAML/Visual Studio错误.我希望其他人发现它不那么奇怪,并且解释为什么我所做的事情是错误的,和/或更好的解决方法,而不仅仅是以不同的顺序声明资源.

我有这个简单的XAML:

<Window x:Class="TestSOAskArrayXaml.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:system="clr-namespace:System;assembly=mscorlib"
        xmlns:local="clr-namespace:TestSOAskArrayXaml"
        Title="MainWindow" Height="350" Width="525">
  <Window.Resources>
    <local:A x:Key="a1"/>
    <x:Array x:Key="listBoxItems" Type="{x:Type system:Double}">
      <system:Double>0.25</system:Double>
    </x:Array>
  </Window.Resources>

  <Grid/>
</Window>
Run Code Online (Sandbox Code Playgroud)

当我尝试编译项目时,我收到以下错误:

1> ... MainWindow.xaml.cs(25,13,​​25,32):错误CS0103:当前上下文中不存在名称"InitializeComponent"

我理解错误的含义,但不是为什么会发生错误.XAML看起来很好,编译它没有错误,但由于某种原因,InitializeComponent()通常放置的自动生成的.gics文件没有被创建或使用(即使文件来自之前成功的编译,它仍然是没有编译成程序集).

如果我只是颠倒资源的顺序,它工作正常:

  <Window.Resources>
    <x:Array x:Key="listBoxItems" Type="{x:Type system:Double}">
      <system:Double>0.25</system:Double>
    </x:Array>
    <local:A x:Key="a1"/>
  </Window.Resources>
Run Code Online (Sandbox Code Playgroud)

附加信息:

  • A是我项目中的任何类.为了这个测试的目的,它被声明为class A { },即一个空类,但我首先遇到这个问题,将转换器实例放入资源.
  • 如果我使用内置类型而不是A,例如<system:String x:Key="a1">Some string</system:String>,错误不会发生.
  • 如果我将一个内置类型的对象作为资源放在用户定义的类型A对象和我的数组资源对象之间,它也可以正常工作!

换句话说,似乎有一个或多个用户定义的类型对象作为第一个资源元素,紧接着是一个数组对象,导致编译失败.其他组合似乎工作得很好.


有人可以解释为什么这是预期的行为(除了重新安排我的资源,我应该做些什么来避免它),或者确认我认为这是XAML构建过程中的错误并不是完全疯了?


编辑:

鉴于这可能是一个真正的错误,我继续在这里打开一个Connect错误报告:https://connect.microsoft.com/VisualStudio/feedback/details/1441123/xaml-fails-to-compile-without-error -if用户自定义对象-是先资源和-随后-立即逐-X-阵列资源

另请参阅相关/类似的Stack Overflow问题:当前上下文中不存在名称"InitializeComponent":奇怪的行为


编辑#2:

WPF更新了Connect报告(参见上面的链接),声明该bug的修复程序将在下一版本的.NET中发布:

Sachin [MSFT]于2016年3月9日下午3:53发布

WPF团队已审核此问题并在下一版本的.NET中修复.我们感谢您的反馈,并考虑解决此问题 - WPF团队

c# wpf xaml compiler-errors

8
推荐指数
1
解决办法
538
查看次数

如何使用lambda创建一个新的EventHandler?

看起来像我应该有我需要这里的一切,但是使它的细节恰巧被我逼疯了.

我有一个静态实用工具方法,它接受一个Web服务客户端对象,从中提取一个指定的EventInfo,并且应该为该事件添加一些处理程序,实质上是Web服务调用完成时的回调.问题是,因为任何给定的事件本身都有自己的处理程序重载(WCF生成的代码SomeMethodCompletedEventArgs为每个方法和相应的事件提供唯一的),我无法弄清楚如何实现这一点.

我有两个我想要附加的处理程序,第一个只是一个lambda函数:

(obj, args) => task.Complete()
Run Code Online (Sandbox Code Playgroud)

所以我想做的就是这么简单:

eventInfo.AddEventHandler(client, new EventHandler((obj, args) => task.Complete()));
Run Code Online (Sandbox Code Playgroud)

但是,这会生成运行时InvalidCastException,因为eventInfo需要一个EventHandler<SomeMethodCompletedEventArgs>而不是一个普通的EventHandler.我相信这意味着我需要以某种方式动态创建EventHandler委托eventInfo.EventHandlerType,但我还没想到要将它与lambda函数结合起来,或者使接收器真的不关心EventArgs正在使用的特定风格.

我发现的唯一解决方法是创建一个通用模板参数,用于传递特定的事件参数类型.这使我能够:

eventInfo.AddEventHandler(client, new EventHandler<E>(...));
Run Code Online (Sandbox Code Playgroud)

E参数在哪里有问题.然而,这显然是笨拙的,当提取的信息eventInfo告诉我们所有我们需要知道的时候,必须通过它似乎是错误的.

值得注意的是,我正在使用一个稍微受限制的Xamarin PCL框架,它显然不包括Delegate.CreateDelegate()我在相关问题中提到的静态方法.不过,我确实可以访问Activator大部分相同的基础.

c# wcf xamarin

7
推荐指数
2
解决办法
1059
查看次数

阅读Jon Skeet关于参考与价值观的章节.仍然困惑

我阅读了Skeet的书的第2.3.2节,根据我的理解,C#中没有真正的引用,就像在C++中一样.

值得注意的是,不仅神话中的"引用"位被破坏,而且"对象被传递"位也是如此.对象本身永远不会通过引用或值传递.当涉及引用类型时,要么通过引用传递变量,要么通过值传递参数(引用)的值.

请注意,这与C++不同(我来自C++背景),因为在C++中,您可以使用&符号直接使用参数列表中的对象 - 没有任何副本,甚至不是对象的内存地址的副本:

bool isEven ( int & i ) { return i % 2 == 0 } )

int main ()
{
    int x = 5; 
    std::cout << isEven(x); // is the exact same as if I had written 
                            // std::cout (x % 2 == 0)
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

没有与上述相同的内容.你能用C#获得的最好成绩相当于

bool isEven ( int * i ) { return *i % 2 == 0 } )

int main ()
{
    int x = 5; 
    std::cout …
Run Code Online (Sandbox Code Playgroud)

c# c++ optimization reference

7
推荐指数
1
解决办法
1027
查看次数

在一行中绑定验证规则?

我已经编写了几个单行绑定,如果可能并且如果它仍然是人类可读的,我想保持这种方式。有没有办法重写这个

<TextBox.Text>
    <Binding Path="SomePath" NotifyOnValidationError="True" >
        <Binding.ValidationRules>
            <local:ValidationRule1></local:ValidationRule1>
        </Binding.ValidationRules>
    </Binding>
</TextBox.Text>
Run Code Online (Sandbox Code Playgroud)

在一行中?,喜欢

<TextBox Text="{Binding Path=SomePath, [ValidationRule1...]}" />
Run Code Online (Sandbox Code Playgroud)

syntax wpf binding

6
推荐指数
1
解决办法
984
查看次数