C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

MultiBinding で Path を生成出来ない。。。

[トピック内 3 記事 (1 - 3 表示)]  << 0 >>

■100718 / inTopicNo.1)  MultiBinding で Path を生成出来ない。。。
  
□投稿者/ 雲 (6回)-(2022/10/21(Fri) 20:27:31)

分類:[.NET 全般] 

MultiBindingを使って Path で図形を描画しようとしていますが、何故か、全く描画されません。
ただの Binding なら問題な図形が描画されるのですが。。。

やっていることは、Resource でIMultiValueConverterを定義して "M 50 0 A 100 50 45 1 0 200 100" を戻しているだけです。

何か気がつくことがあれば、ご指摘頂けると助かります。

==============================================================
windows.xaml
==============================================================
<Window x:Class="ProgressBarControlTemplate.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ProgressBarControlTemplate"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<ControlTemplate x:Key="templateThermometer" TargetType="{x:Type ProgressBar}">
<ControlTemplate.Resources>
<local:PathCreator x:Key="BoolToVisible"/>
<local:xxxConverter x:Key="xxxConverter"/>
</ControlTemplate.Resources>
<Canvas>
<Path Stroke="Red" StrokeThickness="5">
<Path.Data>
<MultiBinding Converter="{StaticResource xxxConverter}">
<Binding RelativeSource="{RelativeSource FindAncestor, AncestorType=Canvas}" Path="ActualWidth"/>
<Binding RelativeSource="{RelativeSource FindAncestor, AncestorType=Canvas}" Path="ActualHeight"/>
</MultiBinding>
</Path.Data>
</Path>
<Path Stroke="Blue" StrokeThickness="5">
<Path.Data>
<Binding Converter="{StaticResource BoolToVisible}"/>
</Path.Data>
</Path>
</Canvas>
</ControlTemplate>
</Window.Resources>
<Grid>
<ProgressBar Template="{StaticResource templateThermometer}" Width="100" Height="300" Value="60" Orientation="Vertical"/>
</Grid>
</Window>

==============================================================
windows.xaml.cs
==============================================================

public class xxxConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
// var a = values.Aggregate((lhs, rhs) => String.Format("{0}:{1}", lhs, rhs));
return( "M 50 0 A 100 50 45 1 0 200 100" );
}

public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
return null;
}
}


public class PathCreator : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
/*
if(value != null)
{
var path = "M 50,0 A 100,50 45 1 0 200,";
path += value.ToString();
return( path );
}
*/
return( "M 50 100 A 100 50 45 1 0 200 100" );
}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
string s = value as string;

if (s != null)
{
int result;
bool isOK = int.TryParse(s, out result);
if (isOK)
{
return result;
}
}

return null;
}
}

引用返信 編集キー/
■100720 / inTopicNo.2)  Re[1]: MultiBinding で Path を生成出来ない。。。
□投稿者/ Hongliang (1255回)-(2022/10/21(Fri) 23:37:17)
IValueConverterの場合、
「Convertから返された値がTargetTypeと異なる型である場合TypeConverterを使って変換を試みる」
という手順があるのですが、IMultiValueConverterにはこれがないみたいですね。

// イメージ
Type targetType = typeof(Geometry);
object value = null;
if (this.Converter is IValueConverter vc) {
    value = vc.Convert(source, targetType, param, culture);
    if (!targetType.IsAssignableFrom(value.GetType())) {
        value = TypeDescryptor.GetConverter(targetType).ConvertFrom(value);
    }
} else if (this.Converter is IMultiValueConverter mvc) {
    value = mvc.Convert(sources, targetType, param, culture);
    // ここが無い
}

Path.DataはGeometry型なので、IMultiValueConverterの場合は正しくこの型
(の派生型)のインスタンスを返す必要があります。
GeometryConverterを使えばお手軽にパスマークアップ文字列からGeometryに変換できます。
(IValueConverterで文字列を返されるときに使われるものでもあります)。

引用返信 編集キー/
■100724 / inTopicNo.3)  Re[2]: MultiBinding で Path を生成出来ない。。。
□投稿者/ 雲 (8回)-(2022/10/22(Sat) 09:57:37)
No100720 (Hongliang さん) に返信
> IValueConverterの場合、
> 「Convertから返された値がTargetTypeと異なる型である場合TypeConverterを使って変換を試みる」
> という手順があるのですが、IMultiValueConverterにはこれがないみたいですね。

まさか、そんな非対称なことがあるとは。。。びっくりしました!

とすると、対応策としては教えて頂いたように TypeConverter で Geometory に変換する
若しくは、(諦めて)C#でGeometoryを構成する。ということですね。

ありがとうございます。スッキリしました。
解決済み
引用返信 編集キー/

このトピックをツリーで一括表示


トピック内ページ移動 / << 0 >>

このトピックに書きこむ