This commit is contained in:
parent
ad8f3983c9
commit
0736345acd
|
|
@ -0,0 +1,39 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Demo.Common.Converters
|
||||
{
|
||||
public class AspectRatioConverter : IMultiValueConverter
|
||||
{
|
||||
private readonly double ratio = 1.777;
|
||||
|
||||
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (values.Length == 2 && values[0] is double height && values[1] is double maxWidth)
|
||||
{
|
||||
Console.WriteLine($@"height {height} maxWidth {maxWidth}");
|
||||
var controlWidth = height * ratio;
|
||||
return controlWidth > maxWidth ? maxWidth : controlWidth;
|
||||
}
|
||||
//else if (values.Length == 4 && values[0] is double stackHeight
|
||||
// && values[1] is double stackWidth && values[2] is int userPageSize
|
||||
// && values[3] is Thickness margin)
|
||||
//{
|
||||
// var controlWidth = stackHeight * ratio;
|
||||
//}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Demo.Common.Converters
|
||||
{
|
||||
public class BooleanInverseConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return value is bool boolValue ? !boolValue : false;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return value is bool boolValue ? !boolValue : false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,6 +5,22 @@
|
|||
<Nullable>enable</Nullable>
|
||||
<UseWPF>true</UseWPF>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<ErrorOnDuplicatePublishOutputFiles>false</ErrorOnDuplicatePublishOutputFiles>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="agora_rtc_sdk" Version="4.2.1" />
|
||||
<PackageReference Include="HandyControl" Version="3.5.1" />
|
||||
<PackageReference Include="Masuit.Tools.Core" Version="2024.6.0" />
|
||||
<PackageReference Include="Prism.DryIoc" Version="8.1.97" />
|
||||
<PackageReference Include="RestSharp" Version="112.1.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="AgoraRtcWrapper.lib">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Demo.Common.Dtos
|
||||
{
|
||||
public class BaseApiResult<T>
|
||||
{
|
||||
public int code { get; set; }
|
||||
public string message { get; set; }
|
||||
public T Data { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Demo.Common.Dtos
|
||||
{
|
||||
public class LoginApiResponse
|
||||
{
|
||||
public string token { get; set; }
|
||||
public string refresh_token { get; set; }
|
||||
|
||||
public string userName { get; set; }
|
||||
public int expire { get; set; }
|
||||
public string uid { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
using Agora.Rtc;
|
||||
using Prism.Events;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Demo.Common.Events
|
||||
{
|
||||
public class AudioVolumeIndicationEvent : PubSubEvent<AudioVolumeInfo>
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
using Demo.Common.Models;
|
||||
using Prism.Events;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Demo.Common.Events
|
||||
{
|
||||
public class UserJoinEvent : PubSubEvent<User>
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
using Demo.Common.Models;
|
||||
using Prism.Events;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Demo.Common.Events
|
||||
{
|
||||
public class UserLeaveEvent : PubSubEvent<User>
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
using Demo.Common.Dtos;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using RestSharp;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using DataFormat = RestSharp.DataFormat;
|
||||
|
||||
namespace Demo.Common.Extensions
|
||||
{
|
||||
public static class RestClientExtension
|
||||
{
|
||||
public static async Task<TResult> PostAsync<TResult, TBody>(this RestClient client, TBody body) where TResult : class where TBody : class
|
||||
{
|
||||
RestRequest request = new RestRequest();
|
||||
request.Method = Method.Post;
|
||||
request.RequestFormat = DataFormat.Json;
|
||||
request.AddOrUpdateHeader("Authorization", $"Bearer {Application.Current.Properties["token"]}");
|
||||
request.AddJsonBody(body);
|
||||
var result = await client.PostAsync<BaseApiResult<TResult>>(request);
|
||||
if (result.code != 200)
|
||||
{
|
||||
return result.Data;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
using Agora.Rtc;
|
||||
using Masuit.Tools.Systems;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Demo.Common.Helpers
|
||||
{
|
||||
public class AgoraHelper : IRtcEngineEventHandler
|
||||
{
|
||||
private static uint _localUId;
|
||||
public static IRtcEngine _RtcEngineInstance;
|
||||
public static int Init(string appId, uint localUid = 0)
|
||||
{
|
||||
if (null == _RtcEngineInstance)
|
||||
{
|
||||
_RtcEngineInstance = RtcEngine.CreateAgoraRtcEngine();
|
||||
}
|
||||
RtcEngineContext rtc_engine_ctx = new RtcEngineContext();
|
||||
rtc_engine_ctx.appId = appId;
|
||||
var ret = _RtcEngineInstance.Initialize(rtc_engine_ctx);
|
||||
|
||||
ret = _RtcEngineInstance.InitEventHandler(new RtcEngineEventHandler());
|
||||
|
||||
_localUId = localUid;
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static int UnInit()
|
||||
{
|
||||
if (null != _RtcEngineInstance)
|
||||
{
|
||||
// Dispose engine
|
||||
_RtcEngineInstance.Dispose();
|
||||
_RtcEngineInstance = null;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 渲染用户视频
|
||||
/// </summary>
|
||||
/// <param name="uid"></param>
|
||||
/// <param name="controlHandle"></param>
|
||||
/// <returns></returns>
|
||||
public static int SetupUserVideo(uint uid, long controlHandle)
|
||||
{
|
||||
if (_localUId == uid)
|
||||
{
|
||||
// 本地用户
|
||||
return _RtcEngineInstance.SetupLocalVideo(new VideoCanvas
|
||||
{
|
||||
view = controlHandle,
|
||||
renderMode = RENDER_MODE_TYPE.RENDER_MODE_HIDDEN,
|
||||
mirrorMode = VIDEO_MIRROR_MODE_TYPE.VIDEO_MIRROR_MODE_DISABLED,
|
||||
uid = uid,
|
||||
setupMode = VIDEO_VIEW_SETUP_MODE.VIDEO_VIEW_SETUP_ADD
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
return _RtcEngineInstance.SetupRemoteVideo(new VideoCanvas
|
||||
{
|
||||
view = controlHandle,
|
||||
renderMode = RENDER_MODE_TYPE.RENDER_MODE_HIDDEN,
|
||||
mirrorMode = VIDEO_MIRROR_MODE_TYPE.VIDEO_MIRROR_MODE_DISABLED,
|
||||
uid = uid,
|
||||
setupMode = VIDEO_VIEW_SETUP_MODE.VIDEO_VIEW_SETUP_ADD
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清除已渲染的用户视频
|
||||
/// </summary>
|
||||
/// <param name="uid"></param>
|
||||
/// <param name="controlHandle"></param>
|
||||
/// <returns></returns>
|
||||
public static int ClearUserVideo(uint uid, long controlHandle)
|
||||
{
|
||||
if (_localUId == uid)
|
||||
{
|
||||
// 本地用户
|
||||
// 删除用户渲染
|
||||
return _RtcEngineInstance.SetupLocalVideo(new VideoCanvas
|
||||
{
|
||||
view = controlHandle,
|
||||
uid = uid,
|
||||
setupMode = VIDEO_VIEW_SETUP_MODE.VIDEO_VIEW_SETUP_REMOVE
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
return _RtcEngineInstance.SetupRemoteVideo(new VideoCanvas
|
||||
{
|
||||
view = controlHandle,
|
||||
uid = uid,
|
||||
setupMode = VIDEO_VIEW_SETUP_MODE.VIDEO_VIEW_SETUP_REMOVE
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 渲染用户视频
|
||||
/// </summary>
|
||||
/// <param name="uid"></param>
|
||||
/// <param name="controlHandle"></param>
|
||||
/// <param name="delUid"></param>
|
||||
/// <returns></returns>
|
||||
public static int SetupUserVideo(uint uid, long controlHandle, uint delUid = 0)
|
||||
{
|
||||
if (delUid > 0)
|
||||
{
|
||||
ClearUserVideo(delUid, controlHandle);
|
||||
}
|
||||
return SetupUserVideo(uid, controlHandle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
using Agora.Rtc;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Prism.Ioc;
|
||||
using Prism.Events;
|
||||
using Demo.Common.Events;
|
||||
using Masuit.Tools;
|
||||
|
||||
namespace Demo.Common.Helpers
|
||||
{
|
||||
public class RtcEngineEventHandler : IRtcEngineEventHandler
|
||||
{
|
||||
private readonly IEventAggregator aggregator;
|
||||
public RtcEngineEventHandler()
|
||||
{
|
||||
aggregator = ContainerLocator.Container.Resolve<IEventAggregator>();
|
||||
}
|
||||
|
||||
public override void OnUserJoined(RtcConnection connection, uint remoteUid, int elapsed)
|
||||
{
|
||||
//base.OnUserJoined(connection, remoteUid, elapsed);
|
||||
Console.WriteLine($@"新用户加入: channelId:{connection.channelId} localuid: {connection.localUid} remoteuid:{remoteUid} elapsed: {elapsed}");
|
||||
|
||||
|
||||
//var aggregator = ContainerLocator.Container.Resolve<IEventAggregator>();
|
||||
aggregator.GetEvent<UserJoinEvent>().Publish(new Models.User
|
||||
{
|
||||
Id = remoteUid,
|
||||
UserName = remoteUid.ToString(),
|
||||
IsManager = true,
|
||||
IsLocal = false
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public override void OnUserOffline(RtcConnection connection, uint remoteUid, USER_OFFLINE_REASON_TYPE reason)
|
||||
{
|
||||
//var aggregator = ContainerLocator.Container.Resolve<IEventAggregator>();
|
||||
aggregator.GetEvent<UserLeaveEvent>().Publish(new Models.User
|
||||
{
|
||||
Id = remoteUid,
|
||||
UserName = remoteUid.ToString(),
|
||||
IsManager = true,
|
||||
IsLocal = false
|
||||
});
|
||||
}
|
||||
|
||||
public override void OnAudioVolumeIndication(RtcConnection connection, AudioVolumeInfo[] speakers, uint speakerNumber, int totalVolume)
|
||||
{
|
||||
|
||||
//aggregator.GetEvent<AudioVolumeIndicationEvent>().Publish();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
using Prism.Mvvm;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Demo.Common.Models
|
||||
{
|
||||
public class User : BindableBase
|
||||
{
|
||||
private long id;
|
||||
public long Id
|
||||
{
|
||||
get { return id; }
|
||||
set { SetProperty(ref id, value); }
|
||||
}
|
||||
|
||||
private string userName;
|
||||
public string UserName
|
||||
{
|
||||
get { return userName; }
|
||||
set { SetProperty(ref userName, value); }
|
||||
}
|
||||
private bool isManager;
|
||||
public bool IsManager
|
||||
{
|
||||
get { return isManager; }
|
||||
set { SetProperty(ref isManager, value); }
|
||||
}
|
||||
|
||||
|
||||
private bool isLocal;
|
||||
public bool IsLocal
|
||||
{
|
||||
get { return isLocal; }
|
||||
set { SetProperty(ref isLocal, value); }
|
||||
}
|
||||
|
||||
//private bool isMain;
|
||||
//public bool IsMain
|
||||
//{
|
||||
// get { return isMain; }
|
||||
// set { SetProperty(ref isMain, value); }
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Demo.Common.Models
|
||||
{
|
||||
public class UserInfo
|
||||
{
|
||||
public long Id { get; set; }
|
||||
public string UserName { get; set; }
|
||||
public bool IsManager { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Demo.Common
|
||||
{
|
||||
public static class TestCredentials
|
||||
{
|
||||
public static string Token { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0-windows</TargetFramework> <TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Demo.Services.Interfaces
|
||||
{
|
||||
public interface IAgoraConfigService : IBaseService
|
||||
{
|
||||
Task<string> GetAgoraConfigAsync();
|
||||
Task<string> GetRtcTokenAsync();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Demo.Services.Interfaces
|
||||
{
|
||||
public interface IAgoraEngineService
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Demo.Services.Interfaces
|
||||
{
|
||||
public interface IAuthService : IBaseService
|
||||
{
|
||||
Task<string> LoginAsync();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Demo.Services.Interfaces
|
||||
{
|
||||
public interface IBaseService
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
using Demo.Common.Dtos;
|
||||
using Demo.Services.Interfaces;
|
||||
using RestSharp;
|
||||
using System.Windows;
|
||||
|
||||
namespace Demo.Services
|
||||
{
|
||||
public class AgoraConfigService : BaseService, IAgoraConfigService
|
||||
{
|
||||
public async Task<string> GetAgoraConfigAsync()
|
||||
{
|
||||
RestRequest request = new RestRequest("home/agora-conf");
|
||||
var result = await BaseRestClient.ExecuteAsync<BaseApiResult<string>>(request);
|
||||
if (!result.IsSuccessful || result.Data == null)
|
||||
{
|
||||
MessageBox.Show(result.ErrorMessage);
|
||||
return string.Empty;
|
||||
}
|
||||
return result.Data.Data;
|
||||
}
|
||||
|
||||
public async Task<string> GetRtcTokenAsync()
|
||||
{
|
||||
var request = new RestRequest("room/tk/rtc?roomNum=999").AddHeader("Authorization", "Bearer " + Application.Current.Properties["token"]);
|
||||
var result = await BaseRestClient.ExecuteAsync<BaseApiResult<string>>(request);
|
||||
|
||||
if (result == null || result.Data == null)
|
||||
{
|
||||
MessageBox.Show("token 获取失败");
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
//return result.Data.Data;
|
||||
|
||||
return result.Data.Data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
using Agora.Rtc;
|
||||
using Demo.Services.Interfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Demo.Services
|
||||
{
|
||||
public class AgoraEngineService : IAgoraEngineService
|
||||
{
|
||||
private IRtcEngine _rtcEngine;
|
||||
|
||||
public AgoraEngineService()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
using Demo.Common;
|
||||
using Demo.Common.Dtos;
|
||||
using Demo.Services.Interfaces;
|
||||
using RestSharp;
|
||||
using System.Windows;
|
||||
|
||||
namespace Demo.Services
|
||||
{
|
||||
public class AuthService : BaseService, IAuthService
|
||||
{
|
||||
public async Task<string> LoginAsync()
|
||||
{
|
||||
var restRequest = new RestRequest("auth/login");
|
||||
restRequest.AddBody(new
|
||||
{
|
||||
account = "2",
|
||||
pwd = "c81e728d9d4c2f636f067f89cc14862c"
|
||||
});
|
||||
var response = await BaseRestClient.ExecutePostAsync<BaseApiResult<LoginApiResponse>>(restRequest);
|
||||
if (!response.IsSuccessful || response.Data == null || response.Data.code != 200)
|
||||
{
|
||||
MessageBox.Show("登录失败");
|
||||
return string.Empty;
|
||||
}
|
||||
return response.Data.Data.token;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
using Demo.Common;
|
||||
using Demo.Services.Interfaces;
|
||||
using RestSharp;
|
||||
using System.Windows;
|
||||
|
||||
namespace Demo.Services
|
||||
{
|
||||
public class BaseService : IBaseService
|
||||
{
|
||||
protected RestClient BaseRestClient;
|
||||
public BaseService(RestClient client = null)
|
||||
{
|
||||
BaseRestClient = client ?? new RestClient(new Uri($@"http://192.168.2.9:5192"));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0-windows</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="RestSharp" Version="112.1.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Demo.Common\Demo.Common.csproj" />
|
||||
<ProjectReference Include="..\Demo.Services.Interfaces\Demo.Services.Interfaces.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -5,42 +5,60 @@ VisualStudioVersion = 17.12.35506.116
|
|||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Services", "Services", "{13DA16E8-EB84-4F95-B120-F4CC4B0162E4}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Meeting.V2.Demo.Services", "Meeting.V2.Demo\Services\Meeting.V2.Demo.Services\Meeting.V2.Demo.Services.csproj", "{A4A5CAFF-287C-4833-98B6-D074132ED8BF}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Meeting.V2.Demo.Services.Interfaces", "Meeting.V2.Demo\Services\Meeting.V2.Demo.Services.Interfaces\Meeting.V2.Demo.Services.Interfaces.csproj", "{A4FC67BC-E1AE-48A3-A312-3BBB3FB1BAEB}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Meeting.V2.Demo", "Meeting.V2.Demo\Meeting.V2.Demo\Meeting.V2.Demo.csproj", "{ED1004D9-097A-4AB6-BA74-BD5CB40D9984}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Demo.Common", "Demo.Common\Demo.Common.csproj", "{B8ACCBD2-1C4D-4CF5-BBBD-C0A62DB64C31}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Demo.Services", "Demo.Services\Demo.Services.csproj", "{F1C3D513-854E-447B-B0C8-306963706E85}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Demo.Services.Interfaces", "Demo.Services.Interfaces\Demo.Services.Interfaces.csproj", "{AAB9554E-AF4A-4B94-BFEC-B239DC9DD2A6}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|x64 = Debug|x64
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{A4A5CAFF-287C-4833-98B6-D074132ED8BF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A4A5CAFF-287C-4833-98B6-D074132ED8BF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A4A5CAFF-287C-4833-98B6-D074132ED8BF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A4A5CAFF-287C-4833-98B6-D074132ED8BF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A4FC67BC-E1AE-48A3-A312-3BBB3FB1BAEB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A4FC67BC-E1AE-48A3-A312-3BBB3FB1BAEB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A4FC67BC-E1AE-48A3-A312-3BBB3FB1BAEB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A4FC67BC-E1AE-48A3-A312-3BBB3FB1BAEB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{ED1004D9-097A-4AB6-BA74-BD5CB40D9984}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{ED1004D9-097A-4AB6-BA74-BD5CB40D9984}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{ED1004D9-097A-4AB6-BA74-BD5CB40D9984}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{ED1004D9-097A-4AB6-BA74-BD5CB40D9984}.Debug|x64.Build.0 = Debug|x64
|
||||
{ED1004D9-097A-4AB6-BA74-BD5CB40D9984}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{ED1004D9-097A-4AB6-BA74-BD5CB40D9984}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{ED1004D9-097A-4AB6-BA74-BD5CB40D9984}.Release|x64.ActiveCfg = Release|x64
|
||||
{ED1004D9-097A-4AB6-BA74-BD5CB40D9984}.Release|x64.Build.0 = Release|x64
|
||||
{B8ACCBD2-1C4D-4CF5-BBBD-C0A62DB64C31}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B8ACCBD2-1C4D-4CF5-BBBD-C0A62DB64C31}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B8ACCBD2-1C4D-4CF5-BBBD-C0A62DB64C31}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{B8ACCBD2-1C4D-4CF5-BBBD-C0A62DB64C31}.Debug|x64.Build.0 = Debug|x64
|
||||
{B8ACCBD2-1C4D-4CF5-BBBD-C0A62DB64C31}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B8ACCBD2-1C4D-4CF5-BBBD-C0A62DB64C31}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{B8ACCBD2-1C4D-4CF5-BBBD-C0A62DB64C31}.Release|x64.ActiveCfg = Release|x64
|
||||
{B8ACCBD2-1C4D-4CF5-BBBD-C0A62DB64C31}.Release|x64.Build.0 = Release|x64
|
||||
{F1C3D513-854E-447B-B0C8-306963706E85}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F1C3D513-854E-447B-B0C8-306963706E85}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F1C3D513-854E-447B-B0C8-306963706E85}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{F1C3D513-854E-447B-B0C8-306963706E85}.Debug|x64.Build.0 = Debug|x64
|
||||
{F1C3D513-854E-447B-B0C8-306963706E85}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F1C3D513-854E-447B-B0C8-306963706E85}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F1C3D513-854E-447B-B0C8-306963706E85}.Release|x64.ActiveCfg = Release|x64
|
||||
{F1C3D513-854E-447B-B0C8-306963706E85}.Release|x64.Build.0 = Release|x64
|
||||
{AAB9554E-AF4A-4B94-BFEC-B239DC9DD2A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{AAB9554E-AF4A-4B94-BFEC-B239DC9DD2A6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{AAB9554E-AF4A-4B94-BFEC-B239DC9DD2A6}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{AAB9554E-AF4A-4B94-BFEC-B239DC9DD2A6}.Debug|x64.Build.0 = Debug|x64
|
||||
{AAB9554E-AF4A-4B94-BFEC-B239DC9DD2A6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{AAB9554E-AF4A-4B94-BFEC-B239DC9DD2A6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{AAB9554E-AF4A-4B94-BFEC-B239DC9DD2A6}.Release|x64.ActiveCfg = Release|x64
|
||||
{AAB9554E-AF4A-4B94-BFEC-B239DC9DD2A6}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{A4A5CAFF-287C-4833-98B6-D074132ED8BF} = {13DA16E8-EB84-4F95-B120-F4CC4B0162E4}
|
||||
{A4FC67BC-E1AE-48A3-A312-3BBB3FB1BAEB} = {13DA16E8-EB84-4F95-B120-F4CC4B0162E4}
|
||||
{F1C3D513-854E-447B-B0C8-306963706E85} = {13DA16E8-EB84-4F95-B120-F4CC4B0162E4}
|
||||
{AAB9554E-AF4A-4B94-BFEC-B239DC9DD2A6} = {13DA16E8-EB84-4F95-B120-F4CC4B0162E4}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
x:Class="Meeting.V2.Demo.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:cnt="clr-namespace:Demo.Common.Converters;assembly=Demo.Common"
|
||||
xmlns:local="clr-namespace:Meeting.V2.Demo"
|
||||
xmlns:prism="http://prismlibrary.com/">
|
||||
<Application.Resources>
|
||||
|
|
|
|||
|
|
@ -1,9 +1,14 @@
|
|||
using Meeting.V2.Demo.Services;
|
||||
using Demo.Common.Helpers;
|
||||
using Demo.Services;
|
||||
using Demo.Services.Interfaces;
|
||||
using Meeting.V2.Demo.Services;
|
||||
using Meeting.V2.Demo.Services.Interfaces;
|
||||
using Meeting.V2.Demo.ViewModels;
|
||||
using Meeting.V2.Demo.Views;
|
||||
using Prism.Events;
|
||||
using Prism.Ioc;
|
||||
using Prism.Modularity;
|
||||
using System;
|
||||
using System.Windows;
|
||||
|
||||
namespace Meeting.V2.Demo
|
||||
|
|
@ -21,9 +26,12 @@ namespace Meeting.V2.Demo
|
|||
protected override void RegisterTypes(IContainerRegistry containerRegistry)
|
||||
{
|
||||
containerRegistry.RegisterSingleton<IConfigureService, ConfigureService>();
|
||||
containerRegistry.RegisterSingleton<IAgoraConfigService, AgoraConfigService>();
|
||||
containerRegistry.RegisterSingleton<IAuthService, AuthService>();
|
||||
|
||||
containerRegistry.RegisterForNavigation<VideoView, VideoViewModel>();
|
||||
containerRegistry.RegisterForNavigation<VideoAreaView, VideoAreaViewModel>();
|
||||
containerRegistry.RegisterSingleton<IEventAggregator, EventAggregator>();
|
||||
}
|
||||
|
||||
protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
|
||||
|
|
@ -32,15 +40,24 @@ namespace Meeting.V2.Demo
|
|||
//moduleCatalog.AddModule<ModuleNameModule>();
|
||||
}
|
||||
|
||||
protected override void OnInitialized()
|
||||
protected override async void OnInitialized()
|
||||
{
|
||||
base.OnInitialized();
|
||||
|
||||
var config = Container.Resolve<IConfigureService>();
|
||||
if (config != null)
|
||||
{
|
||||
config.Init();
|
||||
await config.Init();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnExit(ExitEventArgs e)
|
||||
{
|
||||
AgoraHelper.UnInit();
|
||||
Console.WriteLine("推出了!");
|
||||
base.OnExit(e);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,23 +1,39 @@
|
|||
using Demo.Common;
|
||||
using AngleSharp.Io;
|
||||
using Demo.Common;
|
||||
using Demo.Common.Helpers;
|
||||
using Demo.Services.Interfaces;
|
||||
using Meeting.V2.Demo.Views;
|
||||
using Prism.Regions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Meeting.V2.Demo.Services.Interfaces
|
||||
{
|
||||
public class ConfigureService : IConfigureService
|
||||
{
|
||||
private readonly IRegionManager _regionManager;
|
||||
private readonly IRegionManager _regionManager;
|
||||
private readonly IAuthService _authService;
|
||||
|
||||
public ConfigureService(IRegionManager regionManager)
|
||||
public ConfigureService(IRegionManager regionManager, IAuthService authService)
|
||||
{
|
||||
this._regionManager = regionManager;
|
||||
this._regionManager = regionManager;
|
||||
this._authService = authService;
|
||||
}
|
||||
public void Init()
|
||||
public async Task Init()
|
||||
{
|
||||
_regionManager.RegisterViewWithRegion<VideoAreaView>(RegionNames.VideoRegion);
|
||||
var token = await _authService.LoginAsync();
|
||||
if (string.IsNullOrWhiteSpace(token) )
|
||||
{
|
||||
MessageBox.Show("登录失败");
|
||||
return;
|
||||
|
||||
}
|
||||
System.Windows.Application.Current.Properties["token"] = token;
|
||||
//var appid = await _agoraConfigService.GetAgoraConfigAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Meeting.V2.Demo.Services.Interfaces
|
||||
{
|
||||
public interface IConfigureService
|
||||
{
|
||||
void Init();
|
||||
Task Init();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,12 +4,15 @@
|
|||
<TargetFramework>net6.0-windows</TargetFramework>
|
||||
<UseWPF>true</UseWPF>
|
||||
<UseWindowsForms>True</UseWindowsForms>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<ErrorOnDuplicatePublishOutputFiles>false</ErrorOnDuplicatePublishOutputFiles>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<None Remove="Assets\manager.svg" />
|
||||
<None Remove="Assets\more.svg" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="agora_rtc_sdk" Version="4.2.1" />
|
||||
<PackageReference Include="HandyControl" Version="3.5.1" />
|
||||
<PackageReference Include="MahApps.Microsoft.DwayneNeed" Version="1.0.1" />
|
||||
<PackageReference Include="Prism.DryIoc" Version="8.1.97" />
|
||||
|
|
@ -17,8 +20,8 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Demo.Common\Demo.Common.csproj" />
|
||||
<ProjectReference Include="..\Services\Meeting.V2.Demo.Services.Interfaces\Meeting.V2.Demo.Services.Interfaces.csproj" />
|
||||
<ProjectReference Include="..\Services\Meeting.V2.Demo.Services\Meeting.V2.Demo.Services.csproj" />
|
||||
<ProjectReference Include="..\..\Demo.Services.Interfaces\Demo.Services.Interfaces.csproj" />
|
||||
<ProjectReference Include="..\..\Demo.Services\Demo.Services.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Assets\manager.svg" />
|
||||
|
|
|
|||
|
|
@ -1,19 +1,118 @@
|
|||
using Prism.Mvvm;
|
||||
using Agora.Rtc;
|
||||
using Demo.Common.Events;
|
||||
using Demo.Common.Helpers;
|
||||
using Demo.Common.Models;
|
||||
using Demo.Services.Interfaces;
|
||||
using HandyControl.Controls;
|
||||
using HandyControl.Data;
|
||||
using Masuit.Tools;
|
||||
using Prism.Commands;
|
||||
using Prism.Events;
|
||||
using Prism.Mvvm;
|
||||
using System;
|
||||
using System.Windows;
|
||||
|
||||
namespace Meeting.V2.Demo.ViewModels
|
||||
{
|
||||
public class MainWindowViewModel : BindableBase
|
||||
{
|
||||
public MainWindowViewModel(IEventAggregator aggregator, IAgoraConfigService agoraConfigService)
|
||||
{
|
||||
this._aggregator = aggregator;
|
||||
this._agoraConfigService = agoraConfigService;
|
||||
}
|
||||
|
||||
private string _title = "Prism Application";
|
||||
private readonly IEventAggregator _aggregator;
|
||||
private readonly IAgoraConfigService _agoraConfigService;
|
||||
|
||||
public string Title
|
||||
{
|
||||
get { return _title; }
|
||||
set { SetProperty(ref _title, value); }
|
||||
}
|
||||
|
||||
public MainWindowViewModel()
|
||||
private long uid = (DateTime.Now.Ticks % 100000).ToString("D5").ToInt64();
|
||||
public long UId
|
||||
{
|
||||
|
||||
get { return uid; }
|
||||
set { SetProperty(ref uid, value); }
|
||||
}
|
||||
|
||||
private bool isJoin;
|
||||
public bool IsJoin
|
||||
{
|
||||
get { return isJoin; }
|
||||
set { SetProperty(ref isJoin, value); }
|
||||
}
|
||||
|
||||
|
||||
|
||||
public DelegateCommand JoinChannelCommand => new DelegateCommand(JoinChannel);
|
||||
async void JoinChannel()
|
||||
{
|
||||
AgoraHelper.Init("4a4f7be64fa1404ebda74784fe9ac381", (uint)UId);
|
||||
|
||||
var rtcToken = await _agoraConfigService.GetRtcTokenAsync();
|
||||
if (!string.IsNullOrWhiteSpace(rtcToken))
|
||||
Application.Current.Properties["rtctoken"] = rtcToken;
|
||||
|
||||
var result = AgoraHelper._RtcEngineInstance.EnableVideo();
|
||||
Console.WriteLine($@"{nameof(JoinChannel)}-EnableVideo : {result}");
|
||||
|
||||
result = AgoraHelper._RtcEngineInstance.StartPreview(VIDEO_SOURCE_TYPE.VIDEO_SOURCE_CAMERA_PRIMARY);
|
||||
Console.WriteLine($@"{nameof(JoinChannel)}-StartPreview : {result}");
|
||||
|
||||
ChannelMediaOptions options = new ChannelMediaOptions();
|
||||
options.channelProfile.SetValue(CHANNEL_PROFILE_TYPE.CHANNEL_PROFILE_LIVE_BROADCASTING);
|
||||
options.clientRoleType.SetValue(CLIENT_ROLE_TYPE.CLIENT_ROLE_BROADCASTER);
|
||||
// 发布麦克风采集的音频流
|
||||
options.publishMicrophoneTrack.SetValue(true);
|
||||
// 发布摄像头采集的视频流
|
||||
options.publishCameraTrack.SetValue(true);
|
||||
// 自动订阅所有音频流
|
||||
options.autoSubscribeAudio.SetValue(true);
|
||||
// 自动订阅所有视频流
|
||||
options.autoSubscribeVideo.SetValue(true);
|
||||
|
||||
AgoraHelper._RtcEngineInstance.JoinChannel(System.Windows.Application.Current.Properties["rtctoken"].ToString(), "999", (uint)UId, options);
|
||||
|
||||
///启用用户音量提示。
|
||||
AgoraHelper._RtcEngineInstance.EnableAudioVolumeIndication(200, 5, false);
|
||||
|
||||
_aggregator.GetEvent<UserJoinEvent>().Publish(new User
|
||||
{
|
||||
Id = UId,
|
||||
UserName = UId.ToString(),
|
||||
IsManager = true,
|
||||
IsLocal = true
|
||||
});
|
||||
|
||||
IsJoin = !IsJoin;
|
||||
Growl.Success("加入频道成功");
|
||||
}
|
||||
|
||||
public DelegateCommand LeavelChannelCommand => new DelegateCommand(LeavelChannel);
|
||||
void LeavelChannel()
|
||||
{
|
||||
AgoraHelper._RtcEngineInstance.LeaveChannel();
|
||||
AgoraHelper._RtcEngineInstance.StopPreview();
|
||||
AgoraHelper._RtcEngineInstance.DisableVideo();
|
||||
|
||||
|
||||
_aggregator.GetEvent<UserLeaveEvent>().Publish(new User
|
||||
{
|
||||
Id = UId,
|
||||
UserName = UId.ToString(),
|
||||
IsManager = true,
|
||||
IsLocal = true
|
||||
});
|
||||
|
||||
IsJoin = !IsJoin;
|
||||
|
||||
Growl.Success("离开频道成功");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,77 +1,140 @@
|
|||
using Demo.Common.Models;
|
||||
using Demo.Common.Events;
|
||||
using Meeting.V2.Demo.Core.Mvvm;
|
||||
using Prism.Commands;
|
||||
using Prism.Events;
|
||||
using Prism.Regions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Threading;
|
||||
using User = Demo.Common.Models.User;
|
||||
|
||||
namespace Meeting.V2.Demo.ViewModels
|
||||
{
|
||||
public class VideoAreaViewModel : RegionViewModelBase
|
||||
{
|
||||
public VideoAreaViewModel(IRegionManager regionManager) : base(regionManager)
|
||||
public VideoAreaViewModel(IRegionManager regionManager,
|
||||
IEventAggregator aggregator) : base(regionManager)
|
||||
{
|
||||
UserInfos.Add(new UserInfo() { Id = 1, UserName = "张三", IsManager = true });
|
||||
UserInfos.Add(new UserInfo() { Id = 2, UserName = "李四", IsManager = false });
|
||||
this.aggregator = aggregator;
|
||||
|
||||
UinfoProp = new UserInfo
|
||||
aggregator.GetEvent<UserJoinEvent>().Subscribe((a) => Application.Current.Dispatcher.BeginInvoke(() =>
|
||||
{
|
||||
Id = 111,
|
||||
UserName = "王五",
|
||||
IsManager = false
|
||||
};
|
||||
|
||||
UserInfos.Add(a);
|
||||
}));
|
||||
aggregator.GetEvent<UserLeaveEvent>().Subscribe((a) =>
|
||||
{
|
||||
Application.Current.Dispatcher.BeginInvoke(() =>
|
||||
{
|
||||
if (a.IsLocal)
|
||||
{
|
||||
UserInfos.Clear();
|
||||
FocusUser = null;
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < UserInfos.Count; i++)
|
||||
{
|
||||
if (UserInfos[i].Id == a.Id)
|
||||
{
|
||||
UserInfos.RemoveAt(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
//UserInfos.Add(new UserInfo() { Id = 1, UserName = "张三", IsManager = true });
|
||||
//UserInfos.Add(new UserInfo() { Id = 2, UserName = "李四", IsManager = false });
|
||||
//UserInfos.Add(new UserInfo() { Id = 3, UserName = "李四", IsManager = false });
|
||||
//UserInfos.Add(new UserInfo() { Id = 4, UserName = "李四", IsManager = false });
|
||||
//UserInfos.Add(new UserInfo() { Id = 4, UserName = "李四", IsManager = false });
|
||||
//UserInfos.Add(new UserInfo() { Id = 4, UserName = "李四", IsManager = false });
|
||||
}
|
||||
|
||||
private ObservableCollection<UserInfo> userInfos = new();
|
||||
private ObservableCollection<User> userInfos = new();
|
||||
|
||||
/// <summary>
|
||||
/// 用户列表
|
||||
/// </summary>
|
||||
public ObservableCollection<UserInfo> UserInfos
|
||||
public ObservableCollection<User> UserInfos
|
||||
{
|
||||
get { return userInfos; }
|
||||
set { SetProperty(ref userInfos, value); }
|
||||
}
|
||||
|
||||
private string fieldName = "卧槽";
|
||||
public string PropertyNameAA
|
||||
private int userPageSize = 6;
|
||||
/// <summary>
|
||||
/// 每页用户数
|
||||
/// </summary>
|
||||
public int UserPageSize
|
||||
{
|
||||
get { return fieldName; }
|
||||
set { SetProperty(ref fieldName, value); }
|
||||
}
|
||||
|
||||
private UserInfo Uinfo;
|
||||
public UserInfo UinfoProp
|
||||
{
|
||||
get { return Uinfo; }
|
||||
set { SetProperty(ref Uinfo, value); }
|
||||
get { return userPageSize; }
|
||||
set { SetProperty(ref userPageSize, value); }
|
||||
}
|
||||
|
||||
|
||||
public override void OnNavigatedTo(NavigationContext navigationContext)
|
||||
{
|
||||
//base.OnNavigatedTo(navigationContext);
|
||||
private User focusUser;
|
||||
private readonly IEventAggregator aggregator;
|
||||
|
||||
Init();
|
||||
}
|
||||
|
||||
private void Init()
|
||||
/// <summary>
|
||||
/// 焦点用户
|
||||
/// </summary>
|
||||
public User FocusUser
|
||||
{
|
||||
UserInfos.Add(new UserInfo() { Id = 3, UserName = "王五", IsManager = true });
|
||||
UserInfos.Add(new UserInfo() { Id = 4, UserName = "李2", IsManager = false });
|
||||
get { return focusUser; }
|
||||
set { SetProperty(ref focusUser, value); }
|
||||
}
|
||||
|
||||
|
||||
public DelegateCommand TestCommand => new DelegateCommand(ExecuteCommandName);
|
||||
|
||||
void ExecuteCommandName()
|
||||
/// <summary>
|
||||
/// 选择焦点用户
|
||||
/// </summary>
|
||||
public DelegateCommand<User> SelectedUserCommand => new DelegateCommand<User>((u) =>
|
||||
{
|
||||
MessageBox.Show($@"{UserInfos.Count} Id:{string.Join(',', UserInfos.Select(x => x.Id))}");
|
||||
}
|
||||
if (FocusUser != u || FocusUser.Id != u.Id)
|
||||
{
|
||||
FocusUser = u;
|
||||
}
|
||||
});
|
||||
|
||||
///// <summary>
|
||||
///// 选择焦点用户
|
||||
///// </summary>
|
||||
//public DelegateCommand SelectedUserCommand => new DelegateCommand(() =>
|
||||
//{
|
||||
// Console.WriteLine("2222222222222222222222222222");
|
||||
//});
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 用户列表尺寸大小改变事件
|
||||
/// </summary>
|
||||
public DelegateCommand<object> UserStackPanelSizeChangeCommand => new DelegateCommand<object>((e) =>
|
||||
{
|
||||
if (e is StackPanel control)
|
||||
{
|
||||
Console.WriteLine($@"hei:{control.ActualHeight} widht:{control.ActualWidth}");
|
||||
var width = ((control.ActualHeight - 6) * 1.777);
|
||||
|
||||
UserPageSize = (int)Math.Floor(control.ActualWidth / width);
|
||||
if (UserPageSize < UserInfos.Count && UserPageSize > 0)
|
||||
{
|
||||
while (UserInfos.Count != UserPageSize)
|
||||
{
|
||||
UserInfos.RemoveAt(UserInfos.Count - 1);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,39 +1,93 @@
|
|||
using Demo.Common.Models;
|
||||
using Agora.Rtc;
|
||||
using Demo.Common.Events;
|
||||
using Demo.Common.Helpers;
|
||||
using Demo.Common.Models;
|
||||
using Masuit.Tools;
|
||||
using Meeting.V2.Demo.Core.Mvvm;
|
||||
using Meeting.V2.Demo.Views;
|
||||
using Prism.Commands;
|
||||
using Prism.Regions;
|
||||
using Prism.Events;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Meeting.V2.Demo.ViewModels
|
||||
{
|
||||
public class VideoViewModel : RegionViewModelBase
|
||||
public class VideoViewModel : ViewModelBase
|
||||
{
|
||||
public VideoViewModel(IRegionManager regionManager) : base(regionManager)
|
||||
|
||||
private VideoView _view;
|
||||
|
||||
public VideoViewModel()
|
||||
{
|
||||
//aggregator.GetEvent<UserJoinEvent>().Subscribe(RenderVideoView);
|
||||
}
|
||||
|
||||
private UserInfo userInfo;
|
||||
public DelegateCommand<VideoView> LoadedCommand => new DelegateCommand<VideoView>((u) =>
|
||||
{
|
||||
if (u == null)
|
||||
return;
|
||||
Console.WriteLine($@"LoadedCoommand 被执行了!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
|
||||
this._view = u;
|
||||
RenderVideoView();
|
||||
});
|
||||
|
||||
/// <summary>
|
||||
/// 上一次渲染的用户信息
|
||||
/// </summary>
|
||||
private User oldUserInfo;
|
||||
private User userInfo;
|
||||
/// <summary>
|
||||
/// 用户信息
|
||||
/// </summary>
|
||||
public UserInfo UserInfo
|
||||
public User UserInfo
|
||||
{
|
||||
get { return userInfo; }
|
||||
set { SetProperty(ref userInfo, value); }
|
||||
set
|
||||
{
|
||||
oldUserInfo = userInfo.DeepClone();
|
||||
SetProperty(ref userInfo, value);
|
||||
RenderVideoView();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public DelegateCommand OperClickCommand => new DelegateCommand(() =>
|
||||
{
|
||||
MessageBox.Show($@"id:{userInfo.Id} userName:{userInfo.UserName} isManager:{userInfo.IsManager}");
|
||||
Console.WriteLine($@"id:{UserInfo.Id} userName:{UserInfo.UserName} isManager:{UserInfo.IsManager}");
|
||||
UserInfo.IsManager = !UserInfo.IsManager;
|
||||
userInfo.UserName = DateTime.Now.ToString();
|
||||
Console.WriteLine($@"id:{UserInfo.Id} userName:{UserInfo.UserName} isManager:{UserInfo.IsManager}");
|
||||
//MessageBox.Show($@"id:{Id} userName:{UserName} isManager:{IsManager}");
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public void RenderVideoView()
|
||||
{
|
||||
if (_view == null || UserInfo == null || UserInfo.Id <= 0)
|
||||
{
|
||||
if (_view != null)
|
||||
{
|
||||
//_view.pic_frame.Invoke(() =>
|
||||
//{
|
||||
// _view.pic_frame.Refresh();
|
||||
//});
|
||||
|
||||
if (oldUserInfo != null)
|
||||
{
|
||||
AgoraHelper.ClearUserVideo((uint)(oldUserInfo.Id), (long)_view.pic_frame.Handle);
|
||||
_view.pic_frame.Invoke(() =>
|
||||
{
|
||||
_view.pic_frame.Refresh();
|
||||
});
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
AgoraHelper.SetupUserVideo((uint)UserInfo.Id, (long)_view.pic_frame.Handle, (uint)(oldUserInfo == null ? 0 : oldUserInfo.Id));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,14 +3,17 @@
|
|||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:cmn="clr-namespace:Demo.Common;assembly=Demo.Common"
|
||||
xmlns:cnt="clr-namespace:Demo.Common.Converters;assembly=Demo.Common"
|
||||
xmlns:hc="https://handyorg.github.io/handycontrol"
|
||||
xmlns:intertop="clr-namespace:Microsoft.DwayneNeed.Interop;assembly=MahApps.Microsoft.DwayneNeed"
|
||||
xmlns:local="clr-namespace:Meeting.V2.Demo.Views"
|
||||
xmlns:prism="http://prismlibrary.com/"
|
||||
xmlns:wfc="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
|
||||
xmlns:wfh="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"
|
||||
Width="960"
|
||||
Height="640"
|
||||
Width="962"
|
||||
Height="642"
|
||||
MinWidth="1050"
|
||||
MinHeight="642"
|
||||
prism:ViewModelLocator.AutoWireViewModel="True"
|
||||
Background="#252525"
|
||||
CloseButtonForeground="Red"
|
||||
|
|
@ -18,16 +21,55 @@
|
|||
NonClientAreaForeground="White"
|
||||
OtherButtonForeground="White"
|
||||
WindowStartupLocation="CenterScreen">
|
||||
<Window.Resources>
|
||||
<cnt:BooleanInverseConverter x:Key="BoolInverseConverter" />
|
||||
</Window.Resources>
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition Height="55" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<ContentControl prism:RegionManager.RegionName="{x:Static cmn:RegionNames.VideoRegion}" />
|
||||
<DockPanel Grid.Row="1" Background="#242424">
|
||||
<Button Height="45">加入频道</Button>
|
||||
</DockPanel>
|
||||
<ContentControl Grid.Row="0" prism:RegionManager.RegionName="{x:Static cmn:RegionNames.VideoRegion}" />
|
||||
|
||||
<ScrollViewer
|
||||
Grid.RowSpan="2"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalScrollBarVisibility="Hidden">
|
||||
<StackPanel Margin="0,10,10,10" VerticalAlignment="Top" />
|
||||
</ScrollViewer>
|
||||
<StackPanel
|
||||
Grid.Row="1"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Background="#242424"
|
||||
Orientation="Horizontal">
|
||||
<hc:TextBox
|
||||
x:Name="uid"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
hc:InfoElement.Placeholder="输入任意UID"
|
||||
IsEnabled="{Binding IsJoin, Converter={StaticResource BoolInverseConverter}}"
|
||||
Text="{Binding UId}" />
|
||||
<Button
|
||||
Height="45"
|
||||
Margin="10"
|
||||
Command="{Binding JoinChannelCommand}"
|
||||
IsEnabled="{Binding IsJoin, Converter={StaticResource BoolInverseConverter}}">
|
||||
加入频道
|
||||
</Button>
|
||||
<Button
|
||||
Height="45"
|
||||
Margin="10"
|
||||
Command="{Binding LeavelChannelCommand}"
|
||||
IsEnabled="{Binding IsJoin}">
|
||||
离开频道
|
||||
</Button>
|
||||
|
||||
|
||||
</StackPanel>
|
||||
<!--<local:VideoView x:Name="videoVIew" />-->
|
||||
</Grid>
|
||||
|
||||
</hc:Window>
|
||||
|
|
|
|||
|
|
@ -2,38 +2,86 @@
|
|||
x:Class="Meeting.V2.Demo.Views.VideoAreaView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:cnt="clr-namespace:Demo.Common.Converters;assembly=Demo.Common"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
|
||||
xmlns:local="clr-namespace:Meeting.V2.Demo.Views"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:prism="http://prismlibrary.com/"
|
||||
x:Name="root"
|
||||
d:DesignHeight="530"
|
||||
d:DesignWidth="960"
|
||||
prism:ViewModelLocator.AutoWireViewModel="True"
|
||||
mc:Ignorable="d">
|
||||
<UserControl.Resources>
|
||||
<cnt:AspectRatioConverter x:Key="AspectRatioConverter" />
|
||||
</UserControl.Resources>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="*" MaxHeight="155" />
|
||||
<RowDefinition Height="5*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<ItemsControl Padding="10" ItemsSource="{Binding UserInfos}">
|
||||
|
||||
<ItemsControl
|
||||
x:Name="user_vid"
|
||||
Grid.Row="0"
|
||||
Padding="3"
|
||||
ItemsSource="{Binding UserInfos}">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<StackPanel
|
||||
x:Name="stack_users"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Orientation="Horizontal" />
|
||||
Background="#2D3033"
|
||||
Orientation="Horizontal">
|
||||
<!--<i:Interaction.Triggers>
|
||||
<i:EventTrigger EventName="SizeChanged">
|
||||
<i:InvokeCommandAction Command="{Binding UserStackPanelSizeChangeCommand}" CommandParameter="{Binding ElementName=stack_users}" />
|
||||
</i:EventTrigger>
|
||||
</i:Interaction.Triggers>-->
|
||||
</StackPanel>
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<local:VideoView UserName="{Binding UserName}" />
|
||||
<local:VideoView
|
||||
Margin="3"
|
||||
Command="{Binding DataContext.SelectedUserCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Border}}"
|
||||
CommandParameter="{Binding DataContext, RelativeSource={RelativeSource AncestorType=ContentPresenter}}"
|
||||
UserInfo="{Binding DataContext, RelativeSource={RelativeSource AncestorType=ContentPresenter}}">
|
||||
<local:VideoView.Width>
|
||||
<MultiBinding Converter="{StaticResource AspectRatioConverter}">
|
||||
<Binding ElementName="user_vid" Path="ActualHeight" />
|
||||
<Binding ElementName="user_vid" Path="ActualWidth" />
|
||||
<!--<Binding Path="DataContext.UserPageSize" RelativeSource="{RelativeSource AncestorType=UserControl}" />
|
||||
<Binding Path="Margin" RelativeSource="{RelativeSource Mode=Self}" />-->
|
||||
|
||||
</MultiBinding>
|
||||
</local:VideoView.Width>
|
||||
|
||||
|
||||
</local:VideoView>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
<!--<StackPanel Name="stack_user" Orientation="Horizontal" />-->
|
||||
<local:VideoView x:Name="main_video" Grid.Row="1" />
|
||||
<Border
|
||||
x:Name="border_main"
|
||||
Grid.Row="1"
|
||||
Grid.RowSpan="2"
|
||||
Background="#2D3033">
|
||||
<local:VideoView x:Name="main_video" UserInfo="{Binding DataContext.FocusUser, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Border}}">
|
||||
|
||||
<!--<local:VideoView.Width>
|
||||
<MultiBinding Converter="{StaticResource AspectRatioConverter}">
|
||||
<Binding ElementName="border_main" Path="ActualHeight" />
|
||||
<Binding ElementName="border_main" Path="ActualWidth" />
|
||||
</MultiBinding>
|
||||
</local:VideoView.Width>-->
|
||||
|
||||
</local:VideoView>
|
||||
|
||||
</Border>
|
||||
|
||||
<Button Command="{Binding TestCommand}" Content="测试按钮" />
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
|
|
|||
|
|
@ -21,8 +21,10 @@ namespace Meeting.V2.Demo.Views
|
|||
public partial class VideoAreaView : UserControl
|
||||
{
|
||||
public VideoAreaView()
|
||||
{
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
xmlns:cnt="clr-namespace:Demo.Common.Converters;assembly=Demo.Common"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:hc="https://handyorg.github.io/handycontrol"
|
||||
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
|
||||
xmlns:intertop="clr-namespace:Microsoft.DwayneNeed.Interop;assembly=MahApps.Microsoft.DwayneNeed"
|
||||
xmlns:local="clr-namespace:Meeting.V2.Demo.Views"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
|
|
@ -12,14 +13,22 @@
|
|||
xmlns:svgc="http://sharpvectors.codeplex.com/svgc/"
|
||||
xmlns:wfc="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
|
||||
xmlns:wfh="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"
|
||||
MinWidth="160"
|
||||
MinHeight="90"
|
||||
d:DesignHeight="90"
|
||||
d:DesignWidth="160"
|
||||
x:Name="root"
|
||||
MinWidth="135"
|
||||
MinHeight="75"
|
||||
d:DesignHeight="1080"
|
||||
d:DesignWidth="1920"
|
||||
prism:ViewModelLocator.AutoWireViewModel="True"
|
||||
mc:Ignorable="d">
|
||||
<i:Interaction.Triggers>
|
||||
<i:EventTrigger EventName="Loaded">
|
||||
<prism:InvokeCommandAction Command="{Binding LoadedCommand}" CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=UserControl}}" />
|
||||
</i:EventTrigger>
|
||||
</i:Interaction.Triggers>
|
||||
|
||||
<UserControl.Resources>
|
||||
<cnt:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" />
|
||||
<cnt:AspectRatioConverter x:Key="AspectRatioConverter" />
|
||||
</UserControl.Resources>
|
||||
|
||||
<Grid>
|
||||
|
|
@ -31,9 +40,10 @@
|
|||
<WindowsFormsHost x:Name="gridHost">
|
||||
<wfc:PictureBox
|
||||
x:Name="pic_frame"
|
||||
BackColor="#2d3033"
|
||||
BackColor="#000000"
|
||||
Dock="Fill"
|
||||
MouseEnter="pic_frame_MouseEnter"
|
||||
MouseDoubleClick="pic_frame_MouseDoubleClick"
|
||||
MouseLeave="pic_frame_MouseLeave"
|
||||
SizeMode="StretchImage" />
|
||||
</WindowsFormsHost>
|
||||
|
|
@ -61,7 +71,7 @@
|
|||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Bottom"
|
||||
Orientation="Horizontal">
|
||||
<Border Background="#ff801a" Visibility="{Binding UserInfo.IsManager, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
<Border Background="#ff801a" Visibility="{Binding UserInfo.IsManager, Mode=TwoWay, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
<svgc:SvgViewbox
|
||||
x:Name="icon_manager"
|
||||
Margin="3"
|
||||
|
|
@ -76,7 +86,7 @@
|
|||
VerticalAlignment="Center"
|
||||
FontSize="12"
|
||||
Foreground="White"
|
||||
Text="{Binding UserInfo.UserName}" />
|
||||
Text="{Binding UserInfo.UserName, Mode=TwoWay}" />
|
||||
</Border>
|
||||
</StackPanel>
|
||||
<!--#endregion-->
|
||||
|
|
|
|||
|
|
@ -1,20 +1,11 @@
|
|||
using Demo.Common.Models;
|
||||
using Meeting.V2.Demo.ViewModels;
|
||||
using Prism.Events;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace Meeting.V2.Demo.Views
|
||||
{
|
||||
|
|
@ -23,87 +14,41 @@ namespace Meeting.V2.Demo.Views
|
|||
/// </summary>
|
||||
public partial class VideoView : UserControl
|
||||
{
|
||||
|
||||
|
||||
public VideoView()
|
||||
{
|
||||
InitializeComponent();
|
||||
pic_frame.ImageLocation = $@"E:\桌面\Wall\wallhaven-j3m8v5.jpg";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//public UserInfo UserInfo
|
||||
//{
|
||||
// get { return (UserInfo)GetValue(UserInfoProperty); }
|
||||
// set { SetValue(UserInfoProperty, value); }
|
||||
//}
|
||||
|
||||
//// Using a DependencyProperty as the backing store for MyProperty. This enables animation, styling, binding, etc...
|
||||
//public static readonly DependencyProperty UserInfoProperty =
|
||||
// DependencyProperty.Register("UserInfo", typeof(UserInfo), typeof(VideoView), new FrameworkPropertyMetadata(null));
|
||||
|
||||
|
||||
|
||||
public string UserName
|
||||
|
||||
public User UserInfo
|
||||
{
|
||||
get { return (string)GetValue(UserNameProperty); }
|
||||
set {
|
||||
SetValue(UserNameProperty, value); }
|
||||
get { return (User)GetValue(UserInfoProperty); }
|
||||
set { SetValue(UserInfoProperty, value); }
|
||||
}
|
||||
// Using a DependencyProperty as the backing store for UserName. This enables animation, styling, binding, etc...
|
||||
public static readonly DependencyProperty UserNameProperty =
|
||||
DependencyProperty.Register("UserName", typeof(string), typeof(VideoView), new PropertyMetadata("未知名称", new PropertyChangedCallback(OnUserNamePropertyChangedCallback)));
|
||||
|
||||
private static void OnUserNamePropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
// Using a DependencyProperty as the backing store for MyProperty. This enables animation, styling, binding, etc...
|
||||
public static readonly DependencyProperty UserInfoProperty =
|
||||
DependencyProperty.Register("UserInfo", typeof(User), typeof(VideoView), new PropertyMetadata(null, new(OnUserInfoPropertyChangedCallback)));
|
||||
|
||||
private static void OnUserInfoPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (d is VideoView videoView)
|
||||
if (d is VideoView videoView )
|
||||
{
|
||||
videoView.txt_uname.Text = (string)e.NewValue;
|
||||
|
||||
|
||||
var viewDataContext = videoView.DataContext as VideoViewModel;
|
||||
viewDataContext.UserInfo = e.NewValue as User;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//public bool IsManager
|
||||
//{
|
||||
// get { return (bool)GetValue(IsManagerProperty); }
|
||||
// set { SetValue(IsManagerProperty, value); }
|
||||
//}
|
||||
|
||||
//// Using a DependencyProperty as the backing store for IsManager. This enables animation, styling, binding, etc...
|
||||
//public static readonly DependencyProperty IsManagerProperty =
|
||||
// DependencyProperty.Register("IsManager", typeof(bool), typeof(VideoView), new PropertyMetadata(false, new(OnIsManagerPropertyChangedCallback)));
|
||||
|
||||
//private static void OnIsManagerPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
//{
|
||||
// if (d is VideoView videoView)
|
||||
// {
|
||||
// if (e.NewValue is bool b)
|
||||
// {
|
||||
// var db = videoView.DataContext as VideoViewModel;
|
||||
// db.UserInfo.IsManager = b;
|
||||
// //if (b)
|
||||
// //{
|
||||
// // videoView.icon_manager.Visibility = Visibility.Visible;
|
||||
// //}
|
||||
// //else
|
||||
// //{
|
||||
// // videoView.icon_manager.Visibility = Visibility.Collapsed;
|
||||
// //}
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#region 控制右上角操作按钮显示与消失
|
||||
/// <summary>
|
||||
/// 控制操作按钮显示
|
||||
/// </summary>
|
||||
private bool IsOperVisible = false;
|
||||
private bool IsOperVisible = false;
|
||||
|
||||
private void pic_frame_MouseEnter(object sender, EventArgs e)
|
||||
{
|
||||
btn_oper.Visibility = Visibility.Visible;
|
||||
|
|
@ -136,8 +81,45 @@ namespace Meeting.V2.Demo.Views
|
|||
{
|
||||
await Task.Delay(50).ConfigureAwait(false);
|
||||
|
||||
|
||||
IsOperVisible = false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region 命令绑定
|
||||
private void ExcuteCommand()
|
||||
{
|
||||
// 点击操作按钮,触发命令
|
||||
Command?.Execute(CommandParameter);
|
||||
}
|
||||
|
||||
// 依赖属性定义
|
||||
public ICommand Command
|
||||
{
|
||||
get { return (ICommand)GetValue(CommandProperty); }
|
||||
set { SetValue(CommandProperty, value); }
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty CommandProperty =
|
||||
DependencyProperty.Register("Command", typeof(ICommand), typeof(VideoView), new PropertyMetadata(null));
|
||||
|
||||
public object CommandParameter
|
||||
{
|
||||
get { return GetValue(CommandParameterProperty); }
|
||||
set { SetValue(CommandParameterProperty, value); }
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty CommandParameterProperty =
|
||||
DependencyProperty.Register("CommandParameter", typeof(object), typeof(VideoView), new PropertyMetadata(null));
|
||||
|
||||
private void pic_frame_MouseDoubleClick(object sender, System.Windows.Forms.MouseEventArgs e)
|
||||
{
|
||||
ExcuteCommand();
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +0,0 @@
|
|||
namespace Meeting.V2.Demo.Services.Interfaces
|
||||
{
|
||||
public interface IMessageService
|
||||
{
|
||||
string GetMessage();
|
||||
}
|
||||
}
|
||||
|
|
@ -4,4 +4,8 @@
|
|||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="RestSharp" Version="112.1.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Meeting.V2.Demo.Services.Interfaces
|
||||
{
|
||||
public interface IAgoraConfigService : IBaseService
|
||||
{
|
||||
Task GetAgoraConfig();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Meeting.V2.Demo.Services.Interfaces
|
||||
{
|
||||
public interface IBaseService
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\Demo.Common\Demo.Common.csproj" />
|
||||
<ProjectReference Include="..\Meeting.V2.Demo.Services.Interfaces\Meeting.V2.Demo.Services.Interfaces.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
using Meeting.V2.Demo.Services.Interfaces;
|
||||
|
||||
namespace Meeting.V2.Demo.Services
|
||||
{
|
||||
public class MessageService : IMessageService
|
||||
{
|
||||
public string GetMessage()
|
||||
{
|
||||
return "Hello from the Message Service";
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue